给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列, 不是子串。
1.本人思路,双指针,只循环一次
用arr保存目前的字符串,只有当右指针指向的s值在arr中存在,则左指针直接+=这个值在s中的位置。每次循环右指针右移并且使用slice保存更新arr(因为slice截取第一个参数位置的值,不取第二个参数位置的值,取左不取右),更新maxL
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function (s) {
let n = s.length
if (n == 1) {
return 1
}
let left = 0
let right = 1
let maxL = 0
let arr = s.slice(0, 1)
while (right < n) {
if (arr.indexOf(s[right]) !== -1) {
left += arr.indexOf(s[right])+1
}
right++
arr = s.slice(left, right)
maxL = Math.max(maxL, right - left)
}
return maxL
}
看记录,原来以前也做过
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function (s) {
var max = 0
var count = 1
var finger = 1
for (let index = 0; index < s.length; index++ && finger != s.length) {
if (s.indexOf(s[finger]) < finger) {
s = s.slice(s.indexOf(s[finger]) + 1, s.length + 1)
max = max > count ? max : count
count = 1
finger = 1
index = 0
} else {
count++
finger++
max = max > count ? max : count
}
}
return max
}
2.官方解答:滑动窗口
例如 s = “abcab”。 以 s 的 第一位 a 开始,既 (a)bcab 开始,判断最长字符串为 (abc)ab ,以此类推到 s 的最后一位。
var lengthOfLongestSubstring = function(s) {
// 哈希集合,记录每个字符是否出现过
const occ = new Set();
const n = s.length;
// 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
let rk = -1, 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;
}
// 第 i 到 rk 个字符是一个极长的无重复字符子串
ans = Math.max(ans, rk - i + 1);
}
return ans;
};
作者:力扣官方题解
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。