当前位置: 首页> 房产> 家装 > 网站建设教程论坛_潍坊网站建设_网络营销成功案例ppt免费_如何在百度发布信息

网站建设教程论坛_潍坊网站建设_网络营销成功案例ppt免费_如何在百度发布信息

时间:2025/7/11 18:36:09来源:https://blog.csdn.net/m0_74420622/article/details/143990010 浏览次数:0次
网站建设教程论坛_潍坊网站建设_网络营销成功案例ppt免费_如何在百度发布信息

题目描述

        给定一个字符串 s 和一个字符串数组 words words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含  words 中所有字符串以任意顺序排列连接起来的子串。例如,如果 words = ["ab","cd","ef"], 那么 "abcdef", "abefcd""cdabef", "cdefab""efabcd"和 "efcdab" 都是串联子串。 "acdbef" 不是串联子串,因为他不是任何 words 排列的连接。

        返回所有串联子串在 s 中的开始索引。你可以以 任意顺序 返回答案。

示例 1:

输入:s = "barfoothefoobarman", words = ["foo","bar"]
输出:[0,9]
解释:因为 words.length == 2 同时 words[i].length == 3,连接的子字符串的长度必须为 6。
子串 "barfoo" 开始位置是 0。它是 words 中以 ["bar","foo"] 顺序排列的连接。
子串 "foobar" 开始位置是 9。它是 words 中以 ["foo","bar"] 顺序排列的连接。
输出顺序无关紧要。返回 [9,0] 也是可以的。

示例 2:

输入:s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]
输出:[]
解释:因为 words.length == 4 并且 words[i].length == 4,所以串联子串的长度必须为 16。
s 中没有子串长度为 16 并且等于 words 的任何顺序排列的连接。
所以我们返回一个空数组。

示例 3:

输入:s = "barfoofoobarthefoobarman", words = ["bar","foo","the"]
输出:[6,9,12]
解释:因为 words.length == 3 并且 words[i].length == 3,所以串联子串的长度必须为 9。
子串 "foobarthe" 开始位置是 6。它是 words 中以 ["foo","bar","the"] 顺序排列的连接。
子串 "barthefoo" 开始位置是 9。它是 words 中以 ["bar","the","foo"] 顺序排列的连接。
子串 "thefoobar" 开始位置是 12。它是 words 中以 ["the","foo","bar"] 顺序排列的连接。

提示:

  • 1 <= s.length <= 104
  • 1 <= words.length <= 5000
  • 1 <= words[i].length <= 30
  • words[i] 和 s 由小写英文字母组成

解答

class Solution(object):def findSubstring(self, s, words):""":type s: str:type words: List[str]:rtype: List[int]"""# # 思路一:KMP搜索法# def prefix_table(pattern):#     m=len(pattern)#     prefix=[0]*m#     j=0#     for i in range(1,m):#         while j>0 and pattern[i]!=pattern[j]:#             j=prefix[j-1]#         if pattern[i]==pattern[j]:#             j+=1#         prefix[i]=j#     return prefix# def kmp_search(pattern,text):#     m,n=len(pattern),len(text)#     prefix=prefix_table(pattern)#     j=0#     result=[]#     for i in range(n):#         while j>0 and text[i]!=pattern[j]:#             j=prefix[j-1]#         if text[i]==pattern[j]:#             j+=1#         if j==m:#             result.append(i+1-m)#             j=prefix[j-1]#     return result# # 生成所有可能的串联子串# all_patterns=set()# for perm in permutations(words):#     all_patterns.add("".join(perm))# result = []# # 对每个可能的目标串进行 KMP 匹配# for pattern in all_patterns:#     result.extend(kmp_search(pattern,s))# return result# 思路二:if not s or not words:return []# 初始化变量word_len = len(words[0])word_count = len(words)total_len = word_len * word_countwords_freq = {}# 统计 words 中每个单词的频率for word in words:words_freq[word] = words_freq.get(word, 0) + 1result = []# 遍历所有可能的起始点 (最多 word_len 种不同的对齐方式)for i in range(word_len):left = i  # 当前窗口的起始点right = i  # 当前窗口的结束点window_freq = {}count = 0  # 当前窗口内匹配的单词数# 滑动窗口while right + word_len <= len(s):# 取出当前单词word = s[right:right + word_len]right += word_len# 如果是有效单词if word in words_freq:window_freq[word] = window_freq.get(word, 0) + 1# 如果频率不超过要求,增加匹配的单词数if window_freq[word] <= words_freq[word]:count += 1else:# 如果频率超过要求,调整窗口,直到频率合法while window_freq[word] > words_freq[word]:left_word = s[left:left + word_len]window_freq[left_word] -= 1if window_freq[left_word] < words_freq[left_word]:count -= 1left += word_len# 如果窗口内匹配了所有单词,记录起始点if count == word_count:result.append(left)else:# 如果遇到无效单词,直接重置窗口window_freq.clear()count = 0left = rightreturn result          

        思路一,KMP算法:该方法通过生成目标单词的所有排列,并利用 KMP 字符串匹配算法在目标字符串中寻找这些排列的匹配。KMP 算法通过预处理模式字符串,构建前缀函数来加速匹配过程,避免了暴力匹配中的重复计算。尽管 KMP 本身具有线性时间复杂度,但由于需要生成所有可能的单词排列,这使得该方法在多单词组合的情况下计算量大幅增加,导致整体效率不高。

        思路二,滑动窗口法:滑动窗口法通过一个固定大小的窗口在目标字符串中滑动,窗口内的词频统计与目标单词集中的词频进行比较。如果匹配则记录窗口的起始位置,并通过调整窗口来维护频率的合法性。这种方法通过局部更新窗口内容,避免了对整个字符串的重新扫描,通常能够较为高效地处理多个单词的匹配,特别是在目标单词集合较大时具有较低的计算复杂度。

知识拓展: Python中的排列组合

        在 Python 中,排列组合的计算通常可以借助 itertools 库进行实现,或者直接使用 math 库中的一些数学函数来进行相关的数学计算。下面将介绍一些常见的排列组合问题及其在 Python 中的实现方法。

1. 排列(Permutation)

        排列是从一组元素中按照特定顺序选取元素。Python 中没有直接的排列函数,但可以使用 itertools.permutations 来生成排列。

import itertools# 生成从列表 [1, 2, 3] 中选择 2 个元素的所有排列
arr = [1, 2, 3]
perms = itertools.permutations(arr, 2)# 打印所有排列
for perm in perms:print(perm)# 输出为:
# (1, 2)
# (1, 3)
# (2, 1)
# (2, 3)
# (3, 1)
# (3, 2)

        计算排列数:排列数可以通过 math 模块中的 factorial 函数来计算。

import math# 计算从 5 个元素中选取 3 个的排列数
n = 5
k = 3
permutation_count = math.factorial(n) // math.factorial(n - k)
print(permutation_count)# 输出60

2. 组合(Combination)

        组合是从一组元素中选择元素,但不考虑顺序。Python 中可以使用 itertools.combinations 来生成组合。

import itertools# 生成从列表 [1, 2, 3] 中选择 2 个元素的所有组合
arr = [1, 2, 3]
combs = itertools.combinations(arr, 2)# 打印所有组合
for comb in combs:print(comb)# 输出:
# (1, 2)
# (1, 3)
# (2, 3)

        计算组合数:组合数同样可以通过 math 模块中的 factorial 函数来计算。

import math# 计算从 5 个元素中选取 3 个的组合数
n = 5
k = 3
combination_count = math.factorial(n) // (math.factorial(k) * math.factorial(n - k))
print(combination_count)# 输出10

感谢阅读,希望对你有所帮助~

关键字:网站建设教程论坛_潍坊网站建设_网络营销成功案例ppt免费_如何在百度发布信息

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: