给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是"abc",所以其长度为 3。示例 2:
输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是"b",所以其长度为 1。示例 3:
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是"wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"是一个子序列,不是子串。
这道题首先想到的是关于动态规划的方式,动态规划的四要素:
1.原问题与子问题:原问题是最长不重复子串长度,子问题是以当前字符结尾的最长不重复子序列长度。
2.动态规划状态:第i个状态是以第i个字符结尾的最长不重复子序列长度
3.边界状态结值:当前子串的最短不重复子序列长度为1
4.状态转移方程:从最近处开始,比较当前字符与前面的字符是否相等,比较到dp[i-1]的长度或是有重复项的时候停止。
附上代码:(808ms)
class Solution: def lengthOfLongestSubstring(self,s): if s=='': return 0 dp=[1]*len(s) for i in range(len(s)): #print('i:',i) for j in range(i-1,-1,-1): #print(s[i],s[j]) #print(i,j) if s[i]==s[j]: dp[i]=i-j break else: if i-j <= dp[i-1]: dp[i]+=1 else: break return max(dp)
官方题解(140ms):
class Solution: def lengthOfLongestSubstring(self,s): if s=='': return 0 max_num=0 num=0 test='' for i in s: if i not in test: test += i #print(test) num += 1 #print(num) else: test=test[test.index(i)+1:]+i #print(i) if num > max_num: max_num=num num=len(test) #print(test) if num>max_num: max_num=num return max_num
官方题解使用了滑块的方式,利用了字符串的切片进行操作,效率也提高了很多,很不错的方法,值得借鉴。
以后在使用的过程中可以多考虑使用 “in”的这种判断方式。
但是 in的方式在list中的查找效率不是很高,在dict中的查找效率比较高。因为list是使用线性表进行存储的,查找复杂度为O(n),但是dict是使用散列表进行的存储的,查找效率为O(1)。