给定一个字符串 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 由英文字母、数字、符号和空格组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
package cn.fansunion.leecode.array.max;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* 3. 无重复字符的最长子串 <br/>
* 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。<br/>
* <br/>
* 力扣
*
* @author wen.lei@brgroup.com
*
* 2021-12-28
*/
public class LongestSubstringWithoutRepeatingCharacters {
// 输入: s = "abcabcbb"
// 输出: 3
// 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
// abcade
// TODO 很多网友的算法,可读性太差了,不好理解;官网的还可以,就是优化一层循环?
// 已经尝试了各种数据结构,性能差距有的
public int lengthOfLongestSubstringFaster(String s) {
return 0;
}
// 不用ArrayList,LinkedList,维护索引
// 8 ms, 在所有 Java 提交中击败了22.98%的用户
public int lengthOfLongestSubstring(String s) {
int currentMaxSum = 0;
final char[] charArray = s.toCharArray();
int startIndex = 0;
int endIndex = 0;
String currentStr;
for (int index = 0; index < charArray.length;) {
char c = s.charAt(index);
// 无重复字符,中断了
currentStr = s.substring(startIndex, endIndex);
//这里 index 没有++,下方index++,但是可能多走了外层for循环?
if (currentStr.contains(String.valueOf(c))) {
startIndex++;
} else {
index++;
currentMaxSum = Math.max(currentMaxSum, endIndex - startIndex + 1);
endIndex++;
}
}
return currentMaxSum;
}
// 19 ms,在所有 Java 提交中击败了15.53%的用户
// LinkedList
public int lengthOfLongestSubstring2(String s) {
int currentMaxSum = 0;
LinkedList<Character> currentMaxSumList = new LinkedList<>();
final char[] charArray = s.toCharArray();
for (int index = 0; index < charArray.length;) {
char c = s.charAt(index);
// 无重复字符,中断了
if (currentMaxSumList.contains(c)) {
currentMaxSumList.removeFirst();
} else {
currentMaxSumList.add(c);
index++;
currentMaxSum = Math.max(currentMaxSum, currentMaxSumList.size());
}
}
return currentMaxSum;
}
/**
* 解题思路:一次滚动1格,满足条件,才进行到下一格。耗时:2609 ms,超出预期
*
* @param s
* @return
*/
public int lengthOfLongestSubstring3(String s) {
int currentMaxSum = 0;
List<Character> currentMaxSumList = new ArrayList<>();
for (int index = 0; index < s.toCharArray().length;) {
char c = s.charAt(index);
// 无重复字符,中断了
if (currentMaxSumList.contains(c)) {
currentMaxSumList.remove(0);
} else {
currentMaxSumList.add(c);
index++;
currentMaxSum = Math.max(currentMaxSum, currentMaxSumList.size());
}
}
return currentMaxSum;
}
/**
* 之前的错误解法:clear,remove(0)都不行;<br/>
* 以为和LongestContinuousIncreasingSubsequence、MaxConsecutiveOnes思路一致<br/>
* 实际区别还是有的,代码结构比较像<br/>
*
* @param s
* @return
*/
public int lengthOfLongestSubstringError(String s) {
int currentMaxSum = 0;
List<Character> currentMaxSumList = new ArrayList<>();
for (char c : s.toCharArray()) {
// 无重复字符,中断了
if (currentMaxSumList.contains(c)) {
currentMaxSum = Math.max(currentMaxSum, currentMaxSumList.size());
// 第1次错误解法:currentMaxSumList.clear()
currentMaxSumList.remove(0);
// 和同类型题目,需要把当前字符再放进集合里
currentMaxSumList.add(c);
} else {
currentMaxSumList.add(c);
}
}
return Math.max(currentMaxSum, currentMaxSumList.size());
}
}
package test.leecode.array.max;
import org.junit.Assert;
import org.junit.Test;
import cn.fansunion.leecode.array.max.LongestSubstringWithoutRepeatingCharacters;
/**
* @author wen.lei@brgroup.com
*
* 2022-2-25
*/
public class LongestSubstringWithoutRepeatingCharactersTest {
@Test
public void test() {
LongestSubstringWithoutRepeatingCharacters test = new LongestSubstringWithoutRepeatingCharacters();
Assert.assertEquals(5,test.lengthOfLongestSubstring("abcade"));
Assert.assertEquals(3,test.lengthOfLongestSubstring("dvdf"));
Assert.assertEquals(3,test.lengthOfLongestSubstring("pwwkew"));
Assert.assertEquals(3,test.lengthOfLongestSubstring("abcabcbb"));
Assert.assertEquals(1,test.lengthOfLongestSubstring("a"));
Assert.assertEquals(2,test.lengthOfLongestSubstring("ab"));
Assert.assertEquals(2,test.lengthOfLongestSubstring("abab"));
Assert.assertEquals(4,test.lengthOfLongestSubstring("ababcd"));
Assert.assertEquals(5,test.lengthOfLongestSubstring("abababcabcdabcde"));
}
}