首页 > 代码库 > Longest Substring Without Repeating Characters

Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.

一开始解题时,想法比较简单。未考虑时间复杂性,就认为只要找到最大没有重复字符的子串。

第一次尝试时,先得到该字符串的所有子串,除去有重复字符的字符串,这样可以得到最大没有重复字符的子串。在第一次提交以后,Time Limited。有点受挫。这时,尝试在原先的基础上修改。修改的程序中,修改了之前得到字符串所有子串的地方,例如字符串长度为n,从最大的子串长度为n开始,如果有重复支付则舍去,再查找长度为n-1,n-2,直到找到一个没有重复支付的子串。那么这时子串长度就是最大数。但是提交后仍然Time Limited。后来通过查看http://blog.csdn.net/kenden23/article/details/16839757中提到的思想,发现自己一开始的想法太过于复杂。虽然是引用了思想,但是还是贴一下自己的代码。

我的代码实现与上面大神的blog中实现略有不同。感觉自己还是有点复杂。算法实现大概如下:

1、设置了2个数组,一个syn数组其实也就是标志数组,标记某个字符是否已经出现。一个是position数组,记录的是在一段过程中,该字符第一次出现的位置。

2、其实主要思想是,当找到有重复字符时,将开始指针指向该字符第一次出现的位置的后一个位置上,同时记录长度与最大长度进行对比。这样只要扫描一直字符串长度就能把最大长度找出。

代码如下:

 

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int maxLength = 0;
         if(s.equals(""))
         {
             return maxLength = 0;
         }
         int start = 0;
         int end = 0;
         char[] ch = s.toCharArray();
         boolean[] syn = new boolean[128];
         int[] position = new int[128];
         while(end<ch.length)
         {
             if(!syn[ch[end]] || position[ch[end]]<start)
             {
                 syn[ch[end]] = true;
                 position[ch[end]] = end;
             }
             else
             {
                 maxLength = end - start > maxLength?end - start :maxLength;
                 start = position[ch[end]] + 1;
                 position[ch[end]] = end;
                 syn[ch[end]]=true;
             }
             end ++;
         }
         maxLength = end - start >maxLength?end - start :maxLength;
         return maxLength;
    }
   
}