2021-06-30:给定长度为m的字符串aim,以及一个长度为n的字符串str ,问能否在str中找到一个长度为m的连续子串, 使得这个子串刚好由aim的m个字符组成,顺序无所谓, 返回任意满足条件的一个子串的起始位置,未找到返回-1。

福大大 答案2021-06-30:

map+all+滑动窗口。
map:欠账表。
all:总欠账数。

代码用golang编写。代码如下:

package main

import "fmt"

func main() {
    s1 := "moonfdd"
    s2 := "ddf"
    ret := containExactly3(s1, s2)
    fmt.Println(ret)
}

func containExactly3(s1 string, s2 string) int {
    if len(s1) < len(s2) {
        return -1
    }
    M := len(s2)
    count := make([]int, 256)
    for i := 0; i < M; i++ {
        count[s2[i]]++
    }
    all := M
    R := 0
    // 0~M-1
    for ; R < M; R++ { // 最早的M个字符,让其窗口初步形成
        if count[s1[R]] > 0 {
            count[s1[R]]--
            all--
        } else {
            count[s1[R]]--
        }
    }
    // 窗口初步形成了,并没有判断有效无效,决定下一个位置一上来判断
    // 接下来的过程,窗口右进一个,左吐一个
    for ; R < len(s1); R++ {
        if all == 0 { // R-1
            return R - M
        }
        if count[s1[R]] > 0 {
            all--
            count[s1[R]]--
        } else {
            count[s1[R]]--
        }
        if count[s1[R-M]] >= 0 {
            count[s1[R-M]]++
            all++
        } else {
            count[s1[R-M]]++
        }
    }
    if all == 0 {
        return R - M
    } else {
        return -1
    }
}

执行结果如下:
图片


左神java代码