LeetCode 567. 字符串的排列 (滑动窗口&哈希表)

567. 字符串的排列

题意:
  • 第一个字符串的排列之一是第二个字符串的子串
  • 即判断第二个字符串是否包含某个子串,这个子串的字符以及字符数量要求与第一个字符串相同
解法1 (暴力法)
  • 按照第一个字符串的长度找出第二个字符串的所有相应长度的子串
  • 比较每个子串与第一个字符串的字符以及字符数量是否相同 (哈希表)
class Solution {
    public static boolean checkInclusion(String s1, String s2) {
        Map<Character, Integer> map1 = new HashMap<>();
        Map<Character, Integer> map2 = new HashMap<>();
        map1 = countChar(s1);
        
        for (int start = 0; start < s2.length(); start++) {
            map2.clear();
            int end;
            if ((end = start + s1.length() - 1) > s2.length() - 1) break;
            map2 = countChar(s2.substring(start, end + 1));
            if (map2.equals(map1)) return true;

        }
        return false;
    }

    public static Map<Character, Integer> countChar(String s) {
        Map<Character, Integer> map = new HashMap<>();

        for (int i = 0; i < s.length(); i++) {
            if (map.containsKey(s.charAt(i))) {
                map.put(s.charAt(i), map.get(s.charAt(i)) + 1);
            } else {
                map.put(s.charAt(i), 1);
            }
        }
        return map;
    }    
}
解法2 (滑动窗口)
class Solution {
    public static boolean checkInclusion(String s1, String s2) {
        Map<Character, Integer> map1 = new HashMap<>();
        Map<Character, Integer> map2 = new HashMap<>();
        map1 = countChar(s1);

        int start = 0;
        for (int end = 0; end < s2.length(); end++) {

            map2.put(s2.charAt(end), map2.getOrDefault(s2.charAt(end), 0) + 1);

            while (findAll(map1, map2)) {
                if (map2.equals(map1)) return true;
                map2.put(s2.charAt(start), map2.get(s2.charAt(start)) - 1);
                if (Integer.valueOf(0).equals(map2.get(s2.charAt(start)))) map2.remove(s2.charAt(start));
                start++;
            }
        }
        return false;
    }

    public static boolean findAll(Map<Character, Integer> map1, Map<Character, Integer> map2) {
        Set<Map.Entry<Character, Integer>> set = map1.entrySet();
        for (Map.Entry<Character, Integer> entry : set) {
            if (entry.getValue() > map2.getOrDefault(entry.getKey(), 0)) return false;
        }
        return true;
    }

    public static Map<Character, Integer> countChar(String s) {
        Map<Character, Integer> map = new HashMap<>();

        for (int i = 0; i < s.length(); i++) {
            map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1);
        }
        return map;
    }    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值