[LeetCode]Longest Substring Without Repeating Characters

来源:互联网 发布:linux php编译 编辑:程序博客网 时间:2024/06/07 18:46

Description:
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存储不重复的元素,value值为元素坐标。然后遍历字符,没有就put。如果存在,则删除重复字符及之前的所有key和value值。注意:这个时候,起点就是重复字符最开始的地方+1,子串长度为两个重复之间的长度。

code:

public int lengthOfLongestSubstring(String s) {        if(s.length() == 0 || s==null)return 0;        int end = 0;        int start = 0;          Map<Character,Integer> map = new HashMap<Character,Integer>();        int maxLen = 0;        for(int i=0;i<s.length();i++)        {            if(!map.containsKey(s.charAt(i)))            {                end++;                if(maxLen<end)maxLen = end;                map.put(s.charAt(i),i);            }            else//如果元素重复,则删除            {                int temp = map.get(s.charAt(i));                for(int j=start; j<=temp;j++)                {                    map.remove(s.charAt(j));                }                map.put(s.charAt(i),i);                start = temp + 1;                end = i - temp;            }        }        return maxLen;    }

提交了之后,看了别人的解法,了解了以下值得学习的解法:

解法2:
        用一个256位数组asc[](字符共有256个,包括128个扩展字符),字符串中每一个字符的ASCII值对应该字符在数组中的位置。
        如字符a 在 asc[a]中的下标为97。
        初始化数组asc,令每一个元素为-1。定义start,start表示每次无重复字符串的其实点,初始值为0.从i=0开始遍历字符串,如果数组asc中没有出现该字符(asc[ch]==-1),那么令asc[ch]==i,记录下来该字符在字符串中的位置,接着遍历,如果遇到asc[ch]!=-1表示该字符已经出现了,需要将start到j的asc数组中的元素抹掉。然后重置start,令start=max(asc[i]+1,start);
        最后结果为 result=max(result,i-start);

code:

int lengthOfLongestSubstring(string s) {           int result=0;          int a[128];          int i,j,t,start=0;          for(i=0;i<128;i++)              a[i]=-1;          for(i=0;i<s.length();i++)          {                 if(a[s[i]]!=-1)              {                 if(result<i-start)                      result=i-start;                  for(j=start;j<a[s[i]];j++)                      a[j]=-1;                  start=max(start,a[s[i]]+1);               }              a[s[i]]=i;          }          result=max(result,i-start);          return result;       }  

解法3:the basic idea is, keep a hashmap which stores the characters in string as keys and their positions as values, and keep two pointers which define the max substring. move the right pointer to scan through the string , and meanwhile update the hashmap. If the character is already in the hashmap, then move the left pointer to the right of the same character last found. Note that the two pointers can only move forward.

这个算法11行搞定,也是厉害。

   public int lengthOfLongestSubstring(String s) {        if (s.length()==0) return 0;        HashMap<Character, Integer> map = new HashMap<Character, Integer>();        int max=0;        for (int i=0, j=0; i<s.length(); ++i){            if (map.containsKey(s.charAt(i))){                j = Math.max(j,map.get(s.charAt(i))+1);            }            map.put(s.charAt(i),i);            max = Math.max(max,i-j+1);        }        return max;    }
阅读全文
0 0