青训营笔记之最小替换子串长度 | 豆包MarsCode AI刷题

33 阅读2分钟

问题描述

小F得到了一个特殊的字符串,这个字符串只包含字符ASDF,其长度总是4的倍数。他的任务是通过尽可能少的替换,使得ASDF这四个字符在字符串中出现的频次相等。求出实现这一条件的最小子串长度。

测试样例

样例1:

输入:input = "ADDF"
输出:1

样例2:

输入:input = "ASAFASAFADDD"
输出:3

样例3:

输入:input = "SSDDFFFFAAAS"
输出:1

样例4:

输入:input = "AAAASSSSDDDDFFFF"
输出:0

样例5:

输入:input = "AAAADDDDAAAASSSS"
输出:4

解题思路

先用一个 HashMap 来映射字符 ASDF 到索引,然后用一个数组 counts 来记录每个字符的出现次数。接着计算理想频次(字符串长度除以 4),并遍历 counts 数组,计算每个字符的频次与理想频次的差异,累加需要替换的字符总数。最后,如果所有字符的频次已经相等,则返回 0;否则,返回需要替换的字符总数。

算法步骤

  1. 初始化

    • 使用 HashMap 将字符 ASDF 映射到索引 0123
    • 初始化一个长度为 4 的数组 counts,用于记录每个字符的出现次数。
  2. 统计频次

    • 遍历输入字符串 input,根据 HashMap 获取每个字符的索引,并在 counts 数组中相应位置累加出现次数。
  3. 计算理想频次

    • 计算理想频次 len,即字符串长度除以 4。
  4. 计算差异

    • 遍历 counts 数组,计算每个字符的频次与理想频次的差异,并累加需要替换的字符总数 res
  5. 返回结果

    • 返回需要替换的字符总数 res

代码实现


import java.util.HashMap;
import java.util.HashSet;

public class Main {
    static HashMap<Character, Integer> hm = new HashMap<>();
    static {
        hm.put('A', 0);
        hm.put('D', 1);
        hm.put('S', 2);
        hm.put('F', 3);
    }
    static int[] counts;
    static HashSet<Integer> hs;
    public static int solution(String input) {
        counts = new int[4];
        hs = new HashSet<>();
        // Please write your code here
        
        int res = input.length();
        int len = input.length() / 4;

        for(int i = 0; i < input.length(); i++){
            char c = input.charAt(i);
            counts[hm.get(c)]++;
        }
        for(int i = 0; i < 4 ; i++){
            if(counts[i] > len)  hs.add(i);
        }
        if(hs.size() == 0) return 0;
        for(int right = 0, left = 0; right < input.length(); right++){
            int idx = hm.get(input.charAt(right));
            if(hs.contains(idx)){
                counts[idx]--;
                    while(isenough(len)){
                        res = Math.min(res, right - left + 1);
                        int idx2 =  hm.get(input.charAt(left));
                        if(hs.contains(idx2)) counts[idx2]++;
                        left++;
                    }

            }
        }
        return res;
    }
    public static boolean isenough(int len){
        for(Integer key : hs.toArray(new Integer[0])){
            if(counts[key] > len ) return false;
        }
        return true;
    }

}