日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

2024-01-17:lc的30. 串联所有单词的子串

發(fā)布時(shí)間:2024/1/18 windows 22 coder
生活随笔 收集整理的這篇文章主要介紹了 2024-01-17:lc的30. 串联所有单词的子串 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2024-01-17:用go語言,給定一個(gè)字符串 s 和一個(gè)字符串?dāng)?shù)組 words。 words 中所有字符串 長(zhǎng)度相同。

s 中的 串聯(lián)子串 是指一個(gè)包含 words 中所有字符串以任意順序排列連接起來的子串。

例如,如果 words = ["ab","cd","ef"],

那么 "abcdef", "abefcd","cdabef",

"cdefab","efabcd", 和 "efcdab" 都是串聯(lián)子串,

"acdbef" 不是串聯(lián)子串,因?yàn)樗皇侨魏?words 排列的連接。

返回所有串聯(lián)字串在 s 中的開始索引。

你可以以 任意順序 返回答案。

1 <= s.length <= 10^4,

1 <= words.length <= 5000,

1 <= words[i].length <= 30。

words[i] 和 s 由小寫英文字母組成。

輸入:s = "barfoothefoobarman", words = ["foo","bar"]。

輸出:[0,9]。

來自lc的30. 串聯(lián)所有單詞的子串。

答案2024-01-17:

來自左程云。

靈捷3.5

大體過程如下:

  1. 定義一些常量和變量,包括 BASEMAXN,以及存儲(chǔ)結(jié)果的切片 ans。

  2. 實(shí)現(xiàn) hashValue 函數(shù),用于計(jì)算字符串的哈希值。這里使用一個(gè)基于索引的簡(jiǎn)單哈希函數(shù)將字符串映射為一個(gè)唯一的整數(shù)。

  3. 實(shí)現(xiàn) buildHash 函數(shù),用于構(gòu)建字符串的前綴哈希數(shù)組。通過動(dòng)態(tài)規(guī)劃的方式計(jì)算每個(gè)位置的哈希值。

  4. 實(shí)現(xiàn) hashValueRange 函數(shù),用于計(jì)算子串的哈希值。利用前綴哈希數(shù)組,根據(jù)子串的起始和結(jié)束位置計(jì)算哈希值。

  5. 創(chuàng)建一個(gè)哈希表 mapCount 用于存儲(chǔ) words 中每個(gè)單詞的出現(xiàn)次數(shù)。

  6. 構(gòu)建字符串 s 的前綴哈希數(shù)組 hash。

  7. 創(chuàng)建一個(gè)數(shù)組 pow,用于存儲(chǔ) BASE 的冪次方,便于后續(xù)計(jì)算子串的哈希值。

  8. 創(chuàng)建一個(gè)滑動(dòng)窗口 window,用于記錄當(dāng)前窗口中每個(gè)單詞出現(xiàn)的次數(shù)。

  9. 循環(huán)遍歷 s 中每個(gè)起始位置的可能性(即從 0 到 wordLen-1)。

  10. 在每個(gè)起始位置,初始化一個(gè)變量 debt 用于記錄還需要湊齊的單詞數(shù)。

  11. 在每個(gè)起始位置,遍歷 words 中的單詞,依次將其添加到窗口中,并更新 debt 的值。

  12. 如果 debt 等于 0,表示窗口中已經(jīng)包含了所有 words 中的單詞,則將當(dāng)前起始位置加入結(jié)果數(shù)組 ans 中。

  13. 對(duì)于每個(gè)起始位置,向右移動(dòng)窗口,同時(shí)更新窗口中單詞的出現(xiàn)次數(shù)。

  14. 檢查窗口中的哈希值和單詞出現(xiàn)次數(shù)是否符合要求,如果符合則將當(dāng)前起始位置加入結(jié)果數(shù)組 ans 中。

  15. 清空滑動(dòng)窗口 window。

  16. 返回結(jié)果數(shù)組 ans

總的時(shí)間復(fù)雜度:O(n * m * k),其中 n 是字符串 s 的長(zhǎng)度,m 是 words 的長(zhǎng)度,k 是單詞的平均長(zhǎng)度。

總的額外空間復(fù)雜度:O(n),其中 n 是字符串 s 的長(zhǎng)度,主要用于存儲(chǔ)哈希表、前綴哈希數(shù)組和結(jié)果數(shù)組。

go完整代碼如下:

package main

import (
	"fmt"
)

var BASE = 499
var MAXN = 10001

func hashValue(str string) int64 {
	if str == "" {
		return 0
	}
	n := len(str)
	ans := int64(str[0]-'a') + 1
	for j := 1; j < n; j++ {
		ans = ans*int64(BASE) + int64(str[j]-'a') + 1
	}
	return ans
}

func buildHash(str string) []int64 {
	hash := make([]int64, len(str))
	hash[0] = int64(str[0]-'a') + 1
	for j := 1; j < len(str); j++ {
		hash[j] = hash[j-1]*int64(BASE) + int64(str[j]-'a') + 1
	}
	return hash
}

func hashValueRange(l, r int, hash []int64, pow []int64) int64 {
	ans := hash[r-1]
	if l > 0 {
		ans -= hash[l-1] * pow[r-l]
	}
	return ans
}

func findSubstring(s string, words []string) []int {
	var ans []int
	if len(s) == 0 || len(words) == 0 {
		return ans
	}

	wordLen := len(words[0])
	wordNum := len(words)
	allLen := wordLen * wordNum

	mapCount := make(map[int64]int)
	for _, key := range words {
		v := hashValue(key)
		mapCount[v]++
	}

	hash := buildHash(s)
	pow := make([]int64, MAXN)
	pow[0] = 1
	for j := 1; j < MAXN; j++ {
		pow[j] = pow[j-1] * int64(BASE)
	}

	window := make(map[int64]int)

	for init := 0; init < wordLen && init+allLen <= len(s); init++ {
		debt := wordNum
		for l, r, part := init, init+wordLen, 0; part < wordNum; l += wordLen {
			cur := hashValueRange(l, r, hash, pow)
			window[cur]++
			if window[cur] <= mapCount[cur] {
				debt--
			}
			r += wordLen
			part++
		}
		if debt == 0 {
			ans = append(ans, init)
		}

		for l1, r1, l2, r2 := init, init+wordLen, init+allLen, init+allLen+wordLen; r2 <= len(s); l1, r1, l2, r2 = l1+wordLen, r1+wordLen, l2+wordLen, r2+wordLen {
			out := hashValueRange(l1, r1, hash, pow)
			in := hashValueRange(l2, r2, hash, pow)
			window[out]--
			if window[out] < mapCount[out] {
				debt++
			}
			window[in]++
			if window[in] <= mapCount[in] {
				debt--
			}
			if debt == 0 {
				ans = append(ans, r1)
			}
		}

		for key := range window {
			delete(window, key)
		}
	}

	return ans
}

func main() {
	s := "barfoothefoobarman"
	words := []string{"foo", "bar"}

	result := findSubstring(s, words)

	fmt.Println(result)
}

總結(jié)

以上是生活随笔為你收集整理的2024-01-17:lc的30. 串联所有单词的子串的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。