题目:给定两个字符串 s1 和 s2,写一个函数来判断s2是否包含s1 的排列。
换句话说,第一个字符串的排列之一是第二个字符串的子串。

Golang代码实现尝试如下:
示例1:

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

示例2:

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

基于Golang的代码实现如下:


    if s1 == "" {
        return true
    }
    // s1的长度大于s2时,必定不是子串
    l1, l2 := len(s1), len(s2)
    if l1 > l2 {
        return false
    }
    // 获取s1每个字母的频率
    arr1 := [26]int{}
    for _, b := range s1 {
        arr1[b-97]++
    }
    // 向右滑动次数为两个字符串的长度差+1
    for i := 0; i <= l2-l1; i++ {
        // tmp记录s2子串每个字符的频率
        tmp := [26]int{}
        // loc记录s2子串每个字符的第一个位置
        loc := [26]int{}
        // 标记是否发现合适的子串
        flag := true
        // 遍历s2的子串,如果s2的某个字符在1
        for m, b := range s2[i : i+l1] {
            // 记录每个字符第一次出现的位置
            if loc[b-97] == 0 {
                loc[b-97] = m + 1
            }
            // 如果某个字符的频率大于s1中此字符的频率,则此子串肯定错误
            if v := arr1[b-97]; v < tmp[b-97]+1 {
                flag = false
                // 下个子串开始位置直接从此次重复字符的第一次出现之后开始
                i += loc[b-97]
                break
            }
            // 记录子串中该字符的出现频率
            tmp[b-97]++
        }
        // 没有break则频率完全符合
        if flag {
            return true
        }
    }
    return false

邹友
5 声望1 粉丝