LeetCode 03 Longest Substring Without Repeating Characters(最长不重复子序列)

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.


这题主要就是求最长不重复子序列,最容易想到的方法就是暴力,把所有子序列遍历一遍,找到所有不重复的子序列然后选择最长的那个.但是为了对子序列进行遍历此方法时间复杂度为O(n^2),而需要一个数组来存储字母是否出现,则空间复杂度也为(n)

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int maxlen = 0; //最长子序列的长度
        int i,j;
        //双重循环遍历子序列
        for(i = 0; i < s.length(); i++){
            char visit[] = new char[256]; //存放字母状态,0表示未重复,1表示重复
            visit[s.charAt(i)] = 1;
            for(j = i+1; j < s.length(); j++){ 
                if(visit[s.charAt(j)] == 0){ //如果此字符未出现过,就把它标记为1并读取下一个字符
                    visit[s.charAt(j)] = 1;
                }
                //如果这个字符出现过,说明找到一个不重复子序列
                else{
                    //判断此子序列长度和之前找到的子序列的长度
                    if(j-i > maxlen){
                        maxlen = j-i; 
                    }
                    break;
                }
            }
            //如果在j遍历完数组之前就找到了最长不重复子序列,就跳出内层循环.如果没找到,则说明此时最长子序列的末位就是数组的末位,需要将其长度和maxlen进行比较
            if((j==s.length())&&(j-i>maxlen)){
                maxlen = j-i;
            }
        }
        return maxlen;
    }
}

另一种解法,来自http://blog.csdn.net/lwb102063/article/details/52791053
用数组保存每个字母的下标,pre保存不重复子序列的首位下标,初始值为0,遍历数组,找到重复字符时,将pre的值变为这个字符上一次出现的位置的后一位,再寻找下一个不重复子序列,直到遍历完数组,此算法空间时间复杂度都为O(n)
例如:字符串”bcdecdad”
初始时pre指向首个字符,
初始时pre的位置

找到第一个重复字符时pre的位置,此时最长不重复子序列长度为4.从此时pre的位置开始,继续寻找不重复子序列
这里写图片描述

找到另一个重复字符d时pre的位置,从这里开始继续寻找,直到遍历完成
这里写图片描述
代码:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int maxlen = 0;
        int pre = 0;
        int i,j;
        int hashMap[] = new int[256];//定义数组保持字符下标
        Arrays.fill(hashMap,-1); //将数组初始化为-1
        for(i = 0; i < s.length(); i++){
            //如果出现重复字符
            if(hashMap[s.charAt(i)] != -1){
            //这个字符第一次出现的位置在pre之后,那么此时不重复子序列的首位就改变
                if(hashMap[s.charAt(i)] >= pre){
                    pre = hashMap[s.charAt(i)] + 1;
                }
                //保存字符的新位置
                hashMap[s.charAt(i)] = i;
            }else{
                hashMap[s.charAt(i)] = i;
            }
            //判断不重复子序列的最长长度
              maxlen = Math.max(maxlen, i - pre + 1);  
        }
        return maxlen;
    }
}

猜你喜欢

转载自blog.csdn.net/zxm490484080/article/details/79582972