一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情
测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。
怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~
一、题目描述:
-
题目内容
-
题目示例
-
题目解析
- 本题给出一个由"A"、"C"、"G"和"T"组成的字符串s
- 字符串s的长度为0~10000
二、思路分析:
我们已经刷题一段时间了,对于指针类型的已经有了了解。本题将学会新的技能--滑动窗口。
-
什么是滑动窗口?
-
滑动窗口是基于双指针概念,左右指针指向元素之间形式一个范围(窗口)
-
通常滑动窗口分为:固定大小的窗口和动态变化的窗口
-
使用数据类型通常是数组或者字符串
根据本题题意,要求我们在一串字符串中查找子串,判断条件如下:
- 子串要求长度为10
- 子串在字符串s中出现的次数大于1
查看本题示例后,对于本题的解答,无脑是使用滑动窗口的思想就能解答了。(此处有坑)
- 使用for循环对字符串s进行遍历,范围在[0,len(s)-9]
- 因为要求是子串长度为10的,因此使用字符串分片的方法去s[i:i+10]的子串
- 使用第二个for循环,对取出的子串s[i:i+10]在字符串s中查找出现的次数
- 当出现次数大于1并且没有出现ans列表中,则进行添加ans
- 知道遍历完字符串,返回ans结果
使用Python将上述思路实现后,测试几个case无误,提交一看case 30/31,出现超时
ans = []
for i in range(len(s)-9):
tmp = s[i:i+10]
t = 0
for j in range(len(s)-9):
if tmp == s[j:j+10]:
t = t + 1
if t > 1 and tmp not in ans:
ans.append(tmp)
return ans
使用两个for循环,执行效率的确很低,那有什么方式可以优化呢?
- 着力点:必须要干掉一个for循环
- 方法:借助字典,来存储子串在字符串s中出现的次数
- 子串 tmp 作为win字典key,出现的次数作为value
- 当win[tmp]次数大于1时,则ans列表将tmp进行添加
干掉for循环,代码优化如下
ans = []
win = {}
for i in range(len(s) - 9):
tmp = s[i:i + 10]
if tmp in win.keys():
win[tmp] = win[tmp] + 1
else:
win[tmp] = 1
if win[tmp] > 1 and tmp not in ans:
ans.append(tmp)
return ans
由于字符串s长度在0~10000之间,我们可以在代码开始前进行判断,不符合直接返回空列表
if len(s) < 10 or len(s) > 10000:
return ans
三、总结:
本题考察是滑动窗口思想,为了提高运行效率,可以先对字符串范围进行判断。AC提交记录如下:
时间复杂度O(NL),N为字符串长度,L为子串目标长度10 空间复杂度O(NL)
以上是本期内容,欢迎大佬们点赞评论,下期见~~~