java解法

方法:

统计字符数量:先统计字符串中 A、S、D、W 各字符的数量。
计算超出部分:确定每种字符需要移除的多余数量,如果字符数量没有超标,直接返回 0。
滑动窗口:利用滑动窗口技术,动态调整子串范围,寻找满足条件的最短子串:
右边界扩展窗口,直到包含所有多余字符;
左边界收缩窗口,尝试找到更短的符合条件的子串。
滑动窗口关键点:

窗口内的字符数量动态变化,满足条件的窗口是:count 数组中所有值小于等于 0。
每次满足条件时,记录当前窗口长度并继续收缩。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 输入字符串,输出最短子串长度
        System.out.println(minReplacementLength(scanner.next()));
    }

    /**
     * 计算需要移除的最短子串长度,使剩余字符串中 A, S, D, W 数量相等
     */
    public static int minReplacementLength(String moves) {
        int[] count = new int[4];  // 用于记录 'A', 'S', 'D', 'W' 的数量

        // 统计字符串中每种字符的数量
        for (char move : moves.toCharArray()) {
            count[getIndex(move)]++;
        }

        // 每种字符的目标数量
        int avg = moves.length() / 4;

        // 计算多余字符的总数
        int requiredSteps = 0;
        for (int i = 0; i < 4; i++) {
            count[i] -= avg;  // 计算每种字符的超标数量
            if (count[i] > 0) {
                requiredSteps += count[i];  // 记录需要移除的多余字符数
            } else {
                count[i] = 0;  // 负数无意义,重置为 0
            }
        }

        // 如果没有多余字符,直接返回 0
        if (requiredSteps == 0) return 0;

        // 滑动窗口寻找最短子串
        int left = 0, right = 0, minLength = moves.length() + 1;
        while (right < moves.length()) {
            // 窗口右边界扩展,更新当前窗口内的字符数量
            count[getIndex(moves.charAt(right))]--;

            // 当窗口内所有多余字符数量 <= 0 时,尝试收缩窗口
            while (isBalanced(count)) {
                // 更新最短长度
                minLength = Math.min(minLength, right - left + 1);

                // 收缩左边界,恢复被移除的字符数量
                count[getIndex(moves.charAt(left))]++;
                left++;
            }
            right++;
        }

        return minLength;  // 返回最短子串长度
    }

    /**
     * 根据字符返回对应的索引
     * 'A' -> 0, 'S' -> 1, 'D' -> 2, 'W' -> 3
     */
    private static int getIndex(char move) {
        switch (move) {
            case 'A': return 0;
            case 'S': return 1;
            case 'D': return 2;
            case 'W': return 3;
            default: return -1;
        }
    }

    /**
     * 检查当前窗口内的多余字符是否都小于等于 0
     */
    private static boolean isBalanced(int[] count) {
        for (int c : count) {
            if (c > 0) return false;  // 如果存在未满足条件的字符,返回 false
        }
        return true;  // 所有多余字符 <= 0,窗口有效
    }
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C++解法

方法

统计字符总数:首先统计字符串中每个字符 W、A、S 和 D 的数量。
判断是否已经满足条件:如果所有字符的数量已经相等,直接返回 0。
滑动窗口:
用两个指针 left 和 right 表示窗口的左右边界。
窗口右边界向右扩展,减少窗口内字符的数量。
当窗口内的字符数量满足条件(即剩余字符串中所有字符的数量不超过目标值)时,尝试收缩窗口,寻找更短的子串。
关键点

每次窗口内字符数量发生变化时,判断是否满足剩余字符串中字符均衡的条件。
保持窗口动态变化,直到遍历整个字符串。

#include 
#include 
#include 
using namespace std;

/**
 * 计算最短子串长度,使移除该子串后剩余字符串中字符 'W', 'A', 'S', 'D' 的数量均相等
 */
int find_min_replacement(string &s) {
    unordered_map<char, int> count;  // 统计字符数量
    int n = s.size();
    int required = n / 4;  // 每种字符的目标数量

    // 统计字符串中各字符的数量
    for (char c : s) {
        count[c]++;
    }

    // 如果字符已经满足均衡条件,直接返回0
    if (count['W'] == required && count['A'] == required &&
        count['S'] == required && count['D'] == required) {
        return 0;
    }

    int left = 0, right = 0;  // 滑动窗口的左右边界
    int min_len = n;  // 最短子串长度初始化为字符串长度

    // 滑动窗口遍历字符串
    while (right < n) {
        // 窗口右边界字符计数减一
        count[s[right]]--;

        // 窗口有效:剩余字符满足均衡条件
        while (count['W'] <= required && count['A'] <= required &&
               count['S'] <= required && count['D'] <= required) {
            // 更新最短子串长度
            min_len = min(min_len, right - left + 1);

            // 收缩窗口左边界,恢复字符计数
            count[s[left]]++;
            left++;
        }

        // 扩展窗口右边界
        right++;
    }

    return min_len;  // 返回最短子串长度
}

int main() {
    string s;
    cin >> s;  // 输入字符串
    cout << find_min_replacement(s) << endl;  // 输出最短子串长度
    return 0;
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C解法

更新中
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

JS解法

更新中
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

注:本文转载自blog.csdn.net的CodeClimb的文章"https://blog.csdn.net/CodeClimb/article/details/144513876"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!