【每日leecode】Leecode 567. 字符串的排列

本文深入探讨了滑动窗口算法,一种高效解决字符串排列问题的方法。通过两个具体示例,详细讲解了如何利用滑动窗口判断一个字符串是否包含另一个字符串的排列。提供了两种实现方式,包括变长和定长窗口的代码模板。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

567. 字符串的排列

难度中等128

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

换句话说,第一个字符串的排列之一是第二个字符串的子串。

示例1:

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

 

示例2:

输入: s1= "ab" s2 = "eidboaoo"
输出: False

 

注意:

  1. 输入的字符串只包含小写字母
  2. 两个字符串的长度都在 [1, 10,000] 之间

最近有点小忙,虽然刷了题但是没时间写博客,今天就带来这道题

模板

/* 滑动窗口算法框架 */
func slidingWindow( s,  t string) {
    var need, targe = make(map[byte]int), make(map[byte]int)
    for i:=0;i<len(t);i++ {
        need[t[i] - 'a']++
    }
    left, right := 0, 0
    match := 0
    for right < len(s) {
        c := s[right] - 'a' // 先找到right的char
        right++ //前进
        if _, ok := need[c]; ok { //如果 char在need 中
            // 进行窗口内数据的一系列更新
        }
    }
    //...
    for right - left >= len(t) { //当窗口大于s1 的长度 就判断窗口进行缩小

        d := t[left] - 'a' //获取left对应的char
        left++ //left前进
        if _, ok := need[d]; ok { //left 对应的char 在need中 对窗口进行操作
            // 进行窗口内数据的一系列更新
        }
    }
}

第一种模板解法

func checkInclusion(s1 string, s2 string) bool {
    if len(s1) == 0 {
        return true
    }
    if len(s1) > len(s2) {
        return false
    }
    var need, targe = make(map[byte]int), make(map[byte]int)
    for i:=0;i<len(s1);i++ {
        need[s1[i] - 'a']++
    }
    left, right, match := 0, 0, 0
    for right < len(s2) {
        c := s2[right] - 'a' // 先找到right的char
        right++ //前进
        if _, ok := need[c]; ok { //如果 char在need 中
            targe[c]++ //我们的窗口char也加入
            if targe[c] == need[c]{ // 如果窗口和need 的char 相同 match ++
                match++
            }
        }

        for right - left >= len(s1) { //当窗口大于s1 的长度 就判断窗口进行缩小
            if match == len(need) && right - left == len(s1) { //长度满足,match 满足就直接返回
                return true
            }
            d := s2[left] - 'a' //获取left对应的char
            left++ //left前进
            if _, ok := need[d]; ok { //left 对应的char 在need中 对窗口进行操作
                if targe[d] == need[d] {   //首先判断 char 如果在targe和need中的值相同 match--
                    match-- 
                }
                targe[d]-- //减完在减targe中的值,每次都减
            }
        }
    }
    return false
}

第二种对于定长的窗口

func checkInclusion(s1 string, s2 string) bool {
    if len(s1) == 0 {
        return true
    }
    if len(s1) > len(s2) {
        return false
    }
    var need, targe  [26]int
    for i:=0;i<len(s1);i++ {
        need[s1[i]-'a']++
        targe[s2[i]-'a']++
    }
    cur := 0
    window := len(s1)
    
    if targe == need {
        return true
    }
    for cur + window < len(s2) {

        targe[s2[cur] - 'a']--
        targe[s2[cur+window] - 'a']++
        cur++
        if targe == need { //重点是在最后比较,防止出现匹配的字符串在最后出现
            return true
        }
    }

    return false
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值