数据结构与算法学习笔记(训练营五)-经典面试23(ppt-1)

  • 给定字符串str1和str2,求str1的子串中含有str2所有字符的最小子串长度
    【举例】
    str1="abcde",str2="ac"
    因为"abc"包含 str2 所有的字符,并且在满足这一条件的str1的所有子串中,"abc"是 最短的,返回3。
    str1="12345",str2="344" 最小包含子串不存在,返回0。
/**
 * 给定字符串str1和str2,求str1的子串中含有str2所有字符的最小子串长度
 * 【举例】
 * str1="abcde",str2="ac"
 * 因为"abc"包含 str2 所有的字符,并且在满足这一条件的str1的所有子串中,"abc"是 最短的,返回3。
 * str1="12345",str2="344" 最小包含子串不存在,返回0。
 */
public class MinSubStrLen {

    // 建立词频表,和统计str2字符总数all
    // 遍历str1每到一个位置让相应词频表--,all--
    // 当all小于0时移动L,
    public static int minSubStrLen(String str1,String str2){

        char[] c1 = str1.toCharArray();
        char[] c2 = str2.toCharArray();
        // 字符从0~255,比如'a'字符的个数用map[a] = 1
        int[] map = new int[256];

        for(int i = 0;i < c2.length;i++){
            map[c2[i]] += 1;
        }
        int all = str2.length();
        int left = 0;
        int right = 0;
        int min = Integer.MAX_VALUE;
        while (right < str1.length()){
            map[c1[right]]--;
            if(map[c1[right]] >= 0){
                all--;
            }

            if(all == 0){
                // 已经把str2遍历完了,缩小left,left往右移动的过程中只要保持all = 0,那么就是符合题意的子串
                // 当left移动到使all > 0 的时候收集第一当前最小的答案
                while (map[c1[left]] < 0){
                    map[c1[left++]] ++;
                    // 此时all用增加left向右继续移动
                }
                // 当移动到一个位置,使得词频表中的某个字符大于0
                min = Math.min(min,right-left+1);
                all++;
                map[c1[left++]]++;
            }

            right ++;
        }

        return min == Integer.MAX_VALUE ? 0 : min;
    }

    public static void main(String[] args) {

        String str1 = "abcde";
        String str2 = "ac";
        System.out.println(minSubStrLen(str1, str2));
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容