[LeetCode] 无重复字符的最长子串
Posted longhujing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode] 无重复字符的最长子串相关的知识,希望对你有一定的参考价值。
无重复字符的最长子串
题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
思路1
先从一个最简单的方法开始,假设i ~ j
是一个无重复字符的字串,如果j + 1
位置出现了重复的字符,那么就记录这个字符的长度,接着从i + 1
开始,直到下一次再次出现重复字符。重复上述操作即可。很明显这个算法需要两层循环,而且时间复杂度为O(n2)
package com.longhujing.leetcode.t0003;
import java.util.Arrays;
/**
* @author longhujing
*/
public class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
int res = 0;
boolean[] visited = new boolean[128];
for (int i = 0; i < s.length(); i++) {
Arrays.fill(visited, false);
visited[s.charAt(i)] = true;
int j = i + 1;
while (!visited[s.charAt(j)]) {
visited[s.charAt(j++)] = true;
}
res = Math.max(res, j - i);
}
return res;
}
}
思路2
第一种解法的缺陷是重复遍历了字符串,注意是遍历。解释一下:假设子串i ~ j
是一个无重复字符的字串,而j + 1
位置会导致重复。第一种思路的解法是从i + 1
从头开始!但是其实根本没有必要,因为可以确定,从i + 1 ~ j
这一段是不可能有重复字符的,所以第一种思路的缺陷在这。假设i ~ j + 1
中是k
位置和j + 1
位置重复了,那么应该舍弃k
位置,构造新字串k + 1 ~ j + 1
,避免重复无效的搜索。
图片来源: https://www.cnblogs.com/mfrank/p/10472651.html
假设初始状态如下:
当to指针到达7号位的时候与6号位重复了,此时应该把from指针放置在6+1即7号位上
package com.longhujing.leetcode.t0003;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* @author longhujing
*/
public class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
int res = 1, start = 0;
Map<Character, Integer> map = new HashMap<>(128);
for (int i = 0; i < s.length(); i++) {
if (map.containsKey(s.charAt(i))) {
start = Math.max(start, map.get(s.charAt(i)) + 1);
}
res = Math.max(res, i - start + 1);
map.put(s.charAt(i), i);
}
return res;
}
}
以上是关于[LeetCode] 无重复字符的最长子串的主要内容,如果未能解决你的问题,请参考以下文章