Leetcode 刷题 第六天 – 567. 字符串的排列

Spread the love

567. 字符串的排列

解题思路:此题,我没有看清楚,原来是需要找子串的排列组合在主串的是否存在

// 标准答案,通过26个字母位置统计总数,如果位置相等则保存说明子串与存在主串中
func checkInclusion(s1, s2 string) bool {
    n, m := len(s1), len(s2)
    if n > m {
        return false
    }
    var cnt1, cnt2 [26]int
    for i, ch := range s1 {
        cnt1[ch-'a']++
        cnt2[s2[i]-'a']++
    }
    if cnt1 == cnt2 {
        return true
    }
    for i := n; i < m; i++ {
        cnt2[s2[i]-'a']++
        cnt2[s2[i-n]-'a']--
        if cnt1 == cnt2 {
            return true
        }
    }
    return false
}


// 没有考虑到子串组合
func checkInclusion(s1 string, s2 string) bool {
s1Len := len(s1)
	s2Len := len(s2)

	maxLen := s1Len
	maxS := s1
	minLen := s2Len
	minS := s2
	if s2Len > s1Len {
		maxLen, minLen = minLen, maxLen
		maxS, minS = minS, maxS
	}
	// fmt.Println(maxS, minS)
	j := 0
	for i := 0; i < maxLen; i++ {
		// 正向匹配

		tmp := i
		j = 0
		for j < minLen && tmp < maxLen {
			// fmt.Println(tmp, j, minLen, string(maxS[tmp]), string(minS[j]))
			if maxS[tmp] == minS[j] {
				j++
				tmp++
			} else {
				j = 0
				break
			}
		}
		if j == minLen {
			return true
		}
		// 逆向匹配
		tmp = i
		j = 0
		for j < minLen && tmp < maxLen {
			// fmt.Println(tmp, j, minLen, maxS[tmp], minS[minLen-1-j], minLen-1-j)
			if maxS[tmp] == minS[minLen-1-j] {
				j++
				tmp++
			} else {
				j = 0
				break
			}
		}
		// fmt.Println(j)
		if j == minLen {
			return true
		}
	}

	return false
}

3. 无重复字符的最长子串

解题思路:这条题对比这个字符是否包含在字符串内,方式有快慢指针对比两个数组,滑动窗口,kmp算法,此题需要反转数组在比对,因此kmp不合适

 maxLen := 0
	sLen := len(s)

	for i := 0; i < sLen; i++ {
		j := i
		curHash := make(map[byte]int)
		// fmt.Println(i, j, sLen, s[j])
		for j < sLen && curHash[s[j]] == 0 {
			curHash[s[j]]++
			j++
		}
		// fmt.Println(curHash)
		if maxLen < j-i {
			maxLen = j - i
		}
	}

	return maxLen