[leetcode刷题 C++] 3. Longest Substring Without Repeating Characters

[leetcode刷题 C++] 3. Longest Substring Without Repeating Characters

  • 题目
    Given a string, find the length of the longest substring without repeating characters.

    Example 1:

     Input: "abcabcbb"
     Output: 3 
     Explanation: The answer is "abc", with the length of 3. 
    

    Example 2:

     Input: "bbbbb"
     Output: 1
     Explanation: The answer is "b", with the length of 1.
    

    Example 3:

     Input: "pwwkew"
     Output: 3
     Explanation: 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.

  • 思路
    最基本的思路就是:对于字符串中的每个字符,找到从之开始的最长子字符串的长度,从而找到整个字符串的最长子字符串长度

    那么,怎么找从某个字符开始的最长子字符串?

    • 1 直接遍历
      从指定的字符开始遍历,一直到发现当前字符与之前遍历的字符相同,时间复杂度: O(n^2)
    • 2 滑动窗口
      滑动窗口就是将 [i,j) 作为一个窗口范围,表示从字符 S[i] 开始,到 S[j-1] 这个范围内的字符都不重复。
      对于字符 S[i],我们已经遍历得到了最长子字符串 Si, j-1,那么对于字符 S[i+1] 来说,Si+1,j-1 这个字符串必然是不包含重复的字符的。所以我们不需要每次都重复遍历,只需要判断第 j 个字符是否与 [i,j-1] 中的字符重复:如果不重复,将j加入这个范围,即右窗口往左移; 如果重复,将 i 增加,即窗口往右移,一直移动到与j相同的后一个字符,即将 j‘ + 1 (因为这些字符串必然比从i开始的字符串短),可以使用hash表来查询重复的字符,此时时间复杂度O(1)
  1. O(n^3) 直接遍历
    代码如下:

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            int n = s.length();
            int begin, end, max_len = 0; 
            for(begin = 0; begin < n; begin++) {
                end = begin + 1;
                for(end; end < n; end++) {
                    if(foundSame(s, begin, end)) {
                        break;
                    }
                }
                if((end - begin) > max_len) {
                    max_len = end - begin;
                }
            }
            return max_len; 
        }
        
        int foundSame(string s, int begin, int end) {
            if(begin < 0 || end >= s.length()) {
                return 0;
            }
            for(int i = begin; i < end; i++) {
                if(s[i] == s[end])
                    return 1;
            }
            return 0;
        }
    };
    
  2. O(n) 滑动窗口
    代码如下:

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            unordered_map<char, int>  hash_tbl;
            unordered_map<char, int>::iterator it;
            int start, end, max_len = 0;
            for(start = 0, end = 0; end < s.length(); end++) {
                it = hash_tbl.find(s[end]);
                if(it != hash_tbl.end() && it->second >= start) {
                    start = it->second + 1;
                }
                hash_tbl[s[end]] = end;
                max_len = max(max_len, end - start + 1);    
            }
            return max_len;
        }
    };
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值