每天进步一点点
算法开始第三天 无重复最长子串 难度
medium
无重复最长子串
题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
暴力解法 不推荐
思路分析
/**
* 暴力破解
* @param {string} str
* @returns
* 时间复杂度:O(n^2)
* 空间复杂度: O(n) 使用了数组
*/
const longerSubStr = function (str) {
let max = 0
let len = str.length
for (let i = 0; i < len; i++) {
let chars = [str.charAt(i)]
let j = i
let isRepetition = true
while (isRepetition) {
j++
if (j >= len) break
let currentChar = str.charAt(j)
if (!chars.includes(currentChar)) {
chars.push(currentChar)
} else {
isRepetition = false
}
}
max = Math.max(chars.length, max)
}
return max
}
console.time('longerSubStr')
const result = longerSubStr('abcabcbb')
console.timeEnd('longerSubStr') // 0.27m
console.log('>>>><<<', result) //3
哈希 + 双指针
思路分析
定义两个指针l, r。 r 不断自增 将每个字符出现的次数放在哈希表中 如果当前的字符出现过 我们需要将l指针右移 知道当前字符出现次数为1
/**
* 双指针 + 哈希表解法
* 定义两个指针l, r。
* r 不断自增
* 将每个字符出现的次数 如果当前的字符出现过 我们需要将l指针右移
* 时间复杂度:O(n)
* 空间复杂度: O(n)
*/
const longerSubStr1 = function (str) {
let len = str.length
let max = 0
let map = new Map()
for (l = 0, r = 0; r < len; r++) {
let char = str.charAt(r)
let frequency = map.has(char) ? 1 : map.get(char) + 1
map.set(char, frequency)
while (map.get(char) > 1) { // 这个while 再这个循环中最多执行n次
let lChar = str.charAt(l)
let frequency = map.get(lChar) - 1
map.set(lChar, frequency)
i++
}
max = Math.max(max, r - l + 1)
}
return max
}
console.time('longerSubStr')
const result1 = longerSubStr1('abcdefg')
console.timeEnd('longerSubStr') // 0.141ms
console.log('>>>><<<', result1)
BayBay!!!