这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
示例 4:
输入: s = ""
输出: 0
提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
1.暴力求解法
基本方法:
- 逐个生成子字符串
- 看他是否含有不重复字符
复杂度分析
时间复杂度:
- 找到所有子串: O(n*n)
- 判断子串是否仅含有唯一字符:Hash Set O(n),双指针 O(n*n)
- 整体复杂度 : O(nnn)
空间复杂度:
- Hash Set O(m)
可以看到暴力求解法是可以解出来,但是时间复杂度会达到 O(nnn),会有超时的风险。那么有没有优化的解法呢,答案是有的。利用new set() + 滑动窗口法。
2.new set() + 滑动窗口法
整体思路:
1.首先我们需要建一个set,来存放不重复的子串
2.之后通过滑动窗口来进行遍历寻找。
3.遍历所有字符,找出以不同下标字符为开头的最大不重复子串的长度。
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
let occ = new Set();
let n = s.length;
let rk = -1;
let ans = 0;
for(let i =0;i<n;++i){
if(i!=0){
occ.delete(s.charAt(i-1))
}
while(rk+1<n&& !occ.has(s.charAt(rk+1))){
occ.add(s.charAt(rk+1));
++rk;
}
ans = Math.max(ans,rk-i+1)
}
return ans;
};
总结: 今天又是打卡算法题的一天,这个算法题在我参与前端面试的时候经常被提到过,但是还是没有成功做出来,就算用暴力解法解开还会有更优的方法等你,所以遇到这种题就要多刷然后把它吃透