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.
这里我想到了两种解法,一种是利用map,一种是利用数组,思想差不多,但是数组写的貌似有点丑陋,
这道题的主要解法就是判断最长的不重复字符的子串,考虑到如果字符重复的时候,把这个字符上一次出现的地方的后一位作为起点就能够保证字符串没有重复,所以肯定要找到这个重复字符的上一个出现的地方的后一位作为长度计算的地方,所以我想到利用map来以字符作为key,以字符上一次所在的位置作为value,当map不包含key的时候,说明字符还没有重复,当包含的时候就已经重复了,这时候比较len的长度,如果这时候的不重复的字符串的长度大于len那么就把len修改为不重复字符串的长度,然后继续下一次的比较,总的算法复杂度为O(n)。(其实好像画图更容易让人理解,但是我比较懒O__O "…)数组的实现思想也差不多类似
public class Solution3 { /** * 解法一 * @param s * @return */ public int lengthOfLongestSubstring(String s) { Map<Character, Integer> charMap = new HashMap<>(); int strSize = s.length(); int first = 0; int len = 0; int index; char key; for (int last = 0; last < strSize; last++) { key = s.charAt(last); if (charMap.containsKey(key)) { index = charMap.get(key)+1;将first移动到上一次出现这个字符的后一位 if (index > first) {//first必须在上一个字符出现的地方之前,因为可能多个重复的字符会移动到当前的first之前,例如abcddabc first = index; } } if (last - first + 1 > len) { len = last - first+1; } charMap.put(key,last); } return len; } /** * 解法二 * @param s * @return */ public int lengthOfLongestSubstring1(String s) { int[] charArr = new int[256]; int strSize = s.length(); int first = 0; int len = 0; int index; char key; for (int last = 0; last < strSize; last++) { key = s.charAt(last); if (charArr[key] != 0) { if (charArr[key] == -1) { charArr[key] = 0; index = 1; } else { index = charArr[key]+1; } if (index > first) { first = index; } } if (last - first + 1 > len) { len = last - first+1; } if (last == 0) { charArr[key] = -1; } else { charArr[key] = last; } } return len; } }