/**
*
* 题目:
* 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
*
* 示例 1:
* 输入: s = "abcabcbb"
* 输出: 3
* 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
*
* 示例 2:
* 输入: s = "bbbbb"
* 输出: 1
* 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
*
* 示例 3:
* 输入: s = "pwwkew"
* 输出: 3
* 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
* 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
*
* 示例 4:
* 输入: s = ""
* 输出: 0
* abcbabdcbcca
* abcb(a)bdcbcca
* abcba(b)dcbcca
* abcbabd(c)bcca
* abcbabdcb(c)ca
* abcbabdcbcc(a)
*/
public class NoRepeatedNumber {
public static void main(String[] args) {
String s = "abcbabdcbcca";
int xx = lengthOfLongestSubstringx(s);
System.out.println(xx);
}
/**
* 执行用时:2 ms, 在所有 Java 提交中击败了99.13%的用户
* 内存消耗:38 MB, 在所有 Java 提交中击败了98.17%的用户
* 时间复杂度O(n)
* 最优雅方法
* @param s
* @return
*/
public static int lengthOfLongestSubstringx(String s){
int [] dict = new int[256]; //记录ASCII 码字符出现的位置,以字符作为下标
int base = 0,key = 0,i=0,maxSize = 0;
while(key < s.length()){
i = s.charAt(key);
if(dict[i] > base) base = dict[i];
dict[i] = key+1; //以1作为起始位置,下标加1
maxSize = Math.max(maxSize,key-base+1);
key++;
}
return maxSize;
}
/**
* map方式
* 行用时:4 ms, 在所有 Java 提交中击败了87.93%的用户
* 内存消耗:38.4 MB, 在所有 Java 提交中击败了75.47%的用户
* @param s
* @return
*/
public static int lengthOfLongestSubstring2(String s){
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
int max = 0, head =0, temp=0;
for(int i=0;i<s.length();i++){
temp = s.charAt(i);//字符会自动转对应的ASCII
int cursor = map.get(temp)==null ? 0:map.get(temp);
if(cursor > head) head = cursor;
map.put(temp, i+1);
max = Math.max(max, i-head+1);
}
return max;
}
}