题目描述
原题
Description:
Given a string, find the length of the longest substring without repeating characters.
Example 1:
Input: “abcabcbb”
Output: 3
Explanation: The answer is “abc”, with the length of 3.Example 2:
Input: “bbbbb”
Output: 1
Explanation: The answer is “b”, with the length of 1.Example 3:
Input: “pwwkew”
Output: 3
Explanation: The answer is “wke”, with the length of 3.
Note that the answer must be a substring, “pwke” is a subsequence and not a substring.
原题翻译
描述:
给定一个字符串,找到最长的不重复子串的长度。例1:
输入: “abcabcbb”
输出: 3
解释: 最长的不重复子串为"abc",长度为3。例2:
输入: “bbbbb”
输出: 1
解释: 最长的不重复子串为"b",长度为3。例3:
输入: “pwwkew”
输出: 3
解释: 最长的不重复子串为"wke",长度为3。
注意,答案必须是子字符串,“pwke”是子数组而不是子字符串。
解法一
主要思想
遍历String对应的char[],将char和index放入Map,对Map中已有的char进行覆盖。
源码
public class Solution {
public int lengthOfLongestSubstring(String s) {
int len = s.length();
if(len <= 1)
return len;
Map<Character, Integer> map = new HashMap<>();
char[] chars = s.toCharArray();
int temp = 0;
int max = 0;
for(int i = 0; i < len; i++) {
if(!map.containsKey(chars[i])) {
map.put(chars[i], i);
temp++;
} else {
if(i - map.get(chars[i]) > temp) { // 当前字母不在temp里
temp++;
} else {
max = Math.max(max, temp);
temp = i - map.get(chars[i]);
}
map.put(chars[i], i);
}
}
max = Math.max(max, temp);
return max;
}
}
解法二
主要思想
利用StringBuilder的API。
源码
public class Solution {
public int lengthOfLongestSubstring(String s) {
StringBuilder substring = new StringBuilder();
int longestLength = 0;
for(int i =0; i< s.length(); i++) {
String currentLetter = Character.toString(s.charAt(i));
if (substring.indexOf(currentLetter) != -1 ) { // StringBuilder中已存在该字符
longestLength = Math.max(substring.length(), longestLength);
int endIndexToDelete = substring.indexOf(currentLetter) +1;
substring.delete(0, endIndexToDelete);
}
substring.append(currentLetter);
}
longestLength = Math.max(substring.length(), longestLength);
return longestLength;
}
}
解法三
第一名答案,难以想象它竟然是一位中国人给出的(代码里有中文注释)。作为一个中国人,给出一个String,他竟然能想到ascii码…
主要思想
一个boolean[128]表示128个ascii字符。
源码
public class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
boolean[] exist = new boolean[128]; // 表示acii码的128个字符
int max = 0, start = 0; // start用来记录无重复子串的开始位置
for (int i = 0, len = s.length(); i < len; i++) {
char c = s.charAt(i);
if (exist[c]) {
max = Math.max(max, i - start);
// 每次当数组中出现一个重复字符 c 的时候,将之前一个重复的 c 之前的元素设为未出现(exist[i]=false)
for (int j = start; j < i; j++) {
if (s.charAt(j) == c) {
start = j + 1;
break;
}
exist[s.charAt(j)] = false;
}
} else {
exist[c] = true;
}
}
return Math.max(s.length() - start, max);
}