Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, 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.
注意:substring -> "abc"的substring包括"ab","bc","a"等等;必须是连续的,如果不连续如"ac",则叫做subsequence (子序列)
主题思想:计算不包含重复字符的字符串,就是找串中两个相同字符之间的长度的最大值!
代码:
package leetcode;
import java.util.HashMap;
import java.util.Map;
import javax.swing.text.AbstractDocument.LeafElement;
//主要思想:不重复的子字符串一定是被两个相同字符包围!
//转换方向: 计算两个相同字符之间长度,找出长度的最大值!就是子字符串的最大值
//
public class LengthOfLongestSubstring {
public static int lengthOfLongestSubstring(String s) {
int ret = 0;
int a = 0;
Map<Character, Integer> map = new HashMap<>(); //底层是一个扩展了链表的数组(存的是Entry),其中hashcode和键是有联系的
for (int i = 0, start = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (map.containsKey(c)) {
a = (Integer) map.get(c); //固定上一次c出现的位置
start = Math.max(map.get(c) + 1, start); //map.get(c)+1表示从上一个出现过的字符串的下一位开始;保证start在右边
//map.get(c)不应该比start大的么?No,当遍历的子串中包含前面的字符时,就会把start带到前面去;
//这个函数的作用是区别字符串中出现的字符是否为最近出现的 -> 判断是否把当前位置固定为新子字符串的开始
}
ret = Math.max(ret, i - start + 1); //i-start+1 就是计算两个相同字符之间的字符串长度 ,如果比原来的大,替换掉
map.put(c, i); //最后把最新的c放进去;
}
return ret;
}
public static void main(String[] args) {
String s = "abcdezsdwekjxas";
System.out.println(lengthOfLongestSubstring(s));
}
}
图片参考资料:http://my.oschina.net/jdflyfly/blog/283405 ,非常感谢博主!