leetcode:3. Longest Substring Without Repeating Characters

来源:互联网 发布:宁远县优化办 编辑:程序博客网 时间:2024/06/05 07:26

描述

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.

思路

最开始的思路是利用hash,遍历,将遇见过的字符放在一张hash表中,当遍历到在hash表中出现过的字符串的时候,从hash表中的字符串的位置的下一个开始在遍历。时间复杂度(O(nlog(n))见代码二。
由于代码二的时间复杂度有点高,所以稍微优化了一下,出现相同的字符的时候,将该字符前出现的字符全部擦除,性能稍微提升了一点,时间复杂度(O(n))。(见代码一)
可能这里使用了unordered_map,开销有点高。准备这里使用数组来解决这个问题,但是为了更快的刷题,先参考其他人的思路吧。

代码

代码一

class Solution {public:    int lengthOfLongestSubstring(string s) {        unordered_map<int, int> hash;        int max_length = 0, i=0, first_char = 0;        while(i<s.length())        {            if (hash.find(s[i]) == hash.end()) {                hash[s[i]] = i;            }else{                max_length = max(max_length , (int)hash.size());                while(first_char <= hash[s[i]]){                    hash.erase(s[first_char]);                    first_char++;                }                hash[s[i]] = i;            }            i++;        }        max_length = max( max_length , (int)hash.size());        return max_length;    }};

代码二

class Solution {public:    int lengthOfLongestSubstring(string s) {        unordered_map<int, int> hash;        int max_length = 0;        int i=0;        while(i<s.length())        {            if (hash.find(s[i]) == hash.end()) {                hash[s[i]] = i;            }else{                max_length = (max_length>hash.size() ? max_length : hash.size());                i = hash[s[i]];                hash.clear();            }            i++;        }        max_length = (max_length>hash.size() ? max_length : hash.size());        return max_length;    }};

结果

这里写图片描述

他山之玉

C++ O(n) solutioin

class Solution {public:    int lengthOfLongestSubstring(string s) {        if (s.empty()) return 0;        int size = s.size();        int pos[128];        memset(pos, -1, 128 * sizeof(int));        int max = 0;        int offset = 0;     // offset marks the new start of the substring        for (int i=0; i < size; i++) {            char ch = s[i];            if (pos[ch] < offset)   // s[i] doesn't exist in substring,            {                pos[ch] = i; // mark s[i] with its position                max = i+1-offset>max? i + 1 -offset:max;            }            else // s[i] exists in substring            {                offset = pos[ch] + 1;                pos[ch] = i;            }        }        return max;    }};

Java O(n) solution

public class Solution {    public int lengthOfLongestSubstring(String s) {        int max = 0, i =0 , j = 0,index;        int[] hm = new int[128];        while(j<s.length()){            if(hm[s.charAt(j)] == 0){                hm[s.charAt(j)] = j+1;                j++;                if((j-i) > max)                    max = j-i;            }            else {                index = hm[s.charAt(j)];                hm[s.charAt(j)] = 0;                if (i < index)                    i = index;            }        }        return max;    }}

python O(n) solution

class Solution(object):    def lengthOfLongestSubstring(self, s):        last, res, st = {}, 0, 0        for i, v in enumerate(string):            if v not in last or last[v] < st:                res = max(res, i - st + 1)            else:                st = last[v] + 1            last[v] = i        return res

反思

理解字符其实也是数字,那么这个就可以使用数组hash的思路来解决这个问题了

参考资料

c++中String用法总结
c++中unordered_map

0 0