Longest Substring Without Repeating Characters


Given a string, find the length of the longest substring without repeating characters. http://www.lintcode.com/en/problem/longest-substring-without-repeating-characters/

Discussion


需要限定character的范围,小写字母?大写字母?数字?ASCII?

最初的方案是用个hash保存当前的substring,因为要看是否重复嘛,hash查找方便。一旦遇到重复字符,就update hash和最大长度。update hash是把重复字符第一次出现之前的都erase掉。这种情况下是不需要考虑character的范围的,但是提交就是通不过,wrong answer,但是我本地debug出来明明是好的。方案如见Solution 1。

方案2是假定ASCII,定义个256的数组,来表示这个字符有没有出现过。用两个指针,j指向当前字符,如果当前字符有出现过,讲i指向该字符第一次出现位置的下一个位置,然后更新maxlen。这个不难理解,可是实现的时候我觉得太有技巧了,臣妾做不到。。。于是照着这个思想写了Solution 3.

Solution 1


class Solution {
public:
    /**
     * @param s: a string
     * @return: an integer 
     */
    int lengthOfLongestSubstring(string s) {
        // write your code here
        int maxlen = 0;
        unordered_map<char, bool> map;
        for(int i=0; i<s.length(); i++) {
            char c = s[i];
            unordered_map<char, bool>::iterator it=map.find(c);
            if(it != map.end()) {//找到了就更新maxlen,erase map
                if(map.size() > maxlen) {
                    maxlen = map.size();
                }
                map.erase(map.begin(), next(it));//it+1报错,因为iterator类型不支持+operator。所以以后涉及iterator
                //的操作就用next,prve, advance(return void)好了.
            } 
            map[c] = true;
        }
        if(map.size() > maxlen)//最后一个map也要比较
            maxlen = map.size();
        return maxlen;
    }
};

差不多的思路,不用hash的解法:

class Solution {
public:
    /**
     * @param s: a string
     * @return: an integer 
     */
    int lengthOfLongestSubstring(string s) {
        int result = 0;
        if(s.empty()) return result;
        string sub = s.substr(0, 1);
        result = 1;
        int start = 0;
        for(int i=1; i<s.length(); i++) {
            auto pos = sub.find(s[i]);
            if(pos == string::npos) {//non-repeating character
                sub.push_back(s[i]);
            } else {
                sub.erase(sub.begin(), sub.begin() + pos + 1);
                sub.push_back(s[i]);
            }
            if(sub.length() > result) {
                result = sub.length();
            }
        }
        return result;
    }
};

Solution 2



class Solution {
public:
    /**
     * @param s: a string
     * @return: an integer 
     */
    int lengthOfLongestSubstring(string s) {
        // write your code here
        bool exist[256] = {false};
        int i=0; 
        int maxlen = 0;
        for(int j=0; j<s.length(); j++) {
            while(exist[s[j]]) {//如果有重复字符出现,i最终指向重复字符第一次出现的位置的下一个字符,太难想了
                exist[s[i]] = false;
                i++;
            }
            exist[s[j]] = true;
            maxlen = max(j-i+1, maxlen);
        }
        return maxlen;
    }
};

Solution 3


class Solution {
public:
    /**
     * @param s: a string
     * @return: an integer 
     */
    int lengthOfLongestSubstring(string s) {
        // write your code here
        int exist[256];//存的是字符出现的位置
        for(int i=0; i<256; i++) {
            exist[i] = -1;
        }
        int i=0; 
        int maxlen = 0;
        for(int j=0; j<s.length(); j++) {
            if(exist[s[j]] >=i) {//找到出现过的字符的下一个字符
                i = exist[s[j]]+1;
            }
            exist[s[j]] = j;
            maxlen = max(j-i+1, maxlen);
        }
        return maxlen;
    }
};

results matching ""

    No results matching ""