leetcode567. 字符串的排列

leetcode567. 字符串的排列

题目描述

链接: leetcode567.

给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。

换句话说,s1 的排列之一是 s2 的 子串 。

示例1:

输入:s1 = "ab" s2 = "eidbaooo"
输出:true
解释:s2 包含 s1 的排列之一 ("ba").

示例2:
输入:s1= "ab" s2 = "eidboaoo" 输出:false

题解

滑动窗口:

(1)window维护s1各个字符出现的次数

(2)滑动窗口内每一个右边界字符进入窗口后,将该字符频数-1

(3)如果某个字符频数变成负值,即出现次数多了,开始尝试下一个左端点,left++,窗口右移

(4)左边界字符出窗口后,该左边界字符出现次数要重新+1

  • java解法
    public boolean checkInclusion(String s1, String s2) {
        if (s1.length() > s2.length()) {
            return false;
        }
        Map<Character, Integer> window = new HashMap<>(); // 存储s1中各个字符出现的差值
        for (int i = 0; i < s1.length(); ++i) { // 初始化为s1中该字符出现的次数
            window.put(s1.charAt(i), window.getOrDefault(s1.charAt(i), 0) + 1);
        }
        int left = 0;
        int right = 0;
        while (right < s2.length()) {
            Character ch = s2.charAt(right++);
            window.computeIfPresent(ch, (k,v) -> v-1);
            while (left < right && (!window.containsKey(ch) || window.get(ch) < 0)) { // 当s2中该字符出现次数超了,窗口右移
                window.computeIfPresent(s2.charAt(left++), (k,v) -> v+1);
            }
            if (right - left == s1.length()) {
                return true;
            }
        }
        return false;
    }
  • golang解法
func checkInclusion(s1 string, s2 string) bool {
	window := map[byte]int{}
	left, right := 0, 0
	for i := 0; i < len(s1); i++ {
		window[s1[i]]++
	}
	for right < len(s2) {
		ch := s2[right]
		window[ch]--
		right++
		for left < right && window[ch] < 0 {
			window[s2[left]]++
			left++
		}
		if right - left == len(s1) {
			return true
		}
	}
	return false
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值