0
点赞
收藏
分享

微信扫一扫

LeetCode高频算法面试题 - 003 - 无重复字符的最长子串

大家好,我是漫步coding, 最近在整理 2022年LeetCode高频算法面试题 ,感觉好的, 可以点赞、收藏哈。同时有补充的也欢迎大家给出反馈。本文首发于公众号: 漫步coding

LeetCode高频算法面试题 - 003 - 无重复字符的最长子串_最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

题目难度: ★★★

示例 1:

输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成

代码实现

tips: 以下代码是使用Go代码实现的不同解法, 文章最后可以看C++、C、Java、Python实现

1、滑动窗口

  • 1)、滑动窗口由左右两个指针(start, end)组成,其起始位置均为0。 
  • 2)、窗口移动时,让左指针star不变,仅移动右指针end,不断扩大子串。 
  • 3)、子串中是否存在重复字符,我们使用map存储字符出现的位置。   
  • 4)、右指针end的下一个字符是否已经存在于map中,若是,则左指针start右移到该字符出现位置的下一位(因为从左指针start到这一位中间是必然有重复的);否则重复步骤2。
  • 5)、每次刷新窗口时,都要对窗口长度进行计算,若大于原来标记的最大窗口长度,则进行更新。 

另外,要注意一些边界条件,如字符串长度不能为0,否则将导致数组越界;

这样,通过一次遍历就能够得到结果,时间复杂度为O(n)。

图解过程

步骤1、

LeetCode高频算法面试题 - 003 - 无重复字符的最长子串_子串_02

步骤2、

LeetCode高频算法面试题 - 003 - 无重复字符的最长子串_最长子串_03

步骤3、

LeetCode高频算法面试题 - 003 - 无重复字符的最长子串_最长子串_04

步骤4、

LeetCode高频算法面试题 - 003 - 无重复字符的最长子串_子串_05

步骤5、

LeetCode高频算法面试题 - 003 - 无重复字符的最长子串_子串_06

步骤6、

LeetCode高频算法面试题 - 003 - 无重复字符的最长子串_子串_07

func lengthOfLongestSubstring(s string) int {
if len(s) == 0 {
return 0
}
start, end, max := 0,0,0
m := map[byte]int{}
for ; end < len(s); end++{
if _,ok := m[s[end]]; ok {
if m[s[end]] + 1 >= start { // 针对s是"abba", end是3(最后一个a), start是2(第二个b), m[s[end]]=m['a']是0,所以需要更新start
start = m[s[end]] + 1
}
}
m[s[end]] = end
if end - start + 1 > max {
max = end - start + 1
}
}
return max
}

执行结果:

LeetCode高频算法面试题 - 003 - 无重复字符的最长子串_最长子串_08

其他语言版本

C++

// 滑动窗口
// 时间复杂度: O(len(s))
// 空间复杂度: O(len(charset))
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int freq[256] = {0};
int l = 0, r = -1; //滑动窗口为s[l...r]
int res = 0;
// 整个循环从 l == 0; r == -1 这个空窗口开始
// 到l == s.size(); r == s.size()-1 这个空窗口截止
// 在每次循环里逐渐改变窗口, 维护freq, 并记录当前窗口中是否找到了一个新的最优值
while(l < s.size()){
if(r + 1 < s.size() && freq[s[r+1]] == 0){
r++;
freq[s[r]]++;
}else { //r已经到头 || freq[s[r+1]] == 1
freq[s[l]]--;
l++;
}
res = max(res, r-l+1);
}
return res;
}
};

执行结果:

LeetCode高频算法面试题 - 003 - 无重复字符的最长子串_最长子串_09

Java

class Solution {
public static int lengthOfLongestSubstring(String s) {
Map charIndex = new HashMap<>(s.length());
int start =0, maxLength = 0, length = 0;
for (int i =0; i < s.length(); i++) {
Character ch = s.charAt(i);
Integer lastIndex = charIndex.get(ch);
if (Objects.nonNull(lastIndex) && charIndex.get(ch) >= start) {
start = lastIndex + 1;
length = i - start + 1;
} else {
length += 1;
}
maxLength = length > maxLength ? length : maxLength;
charIndex.put(ch, i);
}
return maxLength;
}
}

执行结果:

LeetCode高频算法面试题 - 003 - 无重复字符的最长子串_子串_10

几种语言运行效果对比

LeetCode高频算法面试题 - 003 - 无重复字符的最长子串_滑动窗口_11

举报

相关推荐

0 条评论