zoukankan      html  css  js  c++  java
  • [LeetCode] 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.

      这道题经过了一番苦苦挣扎还是没能解出来。虽然借助哈希表可以弄到O(n^2)但是题目要求是O(n),感觉有用点DP的技巧,其实基本思想就是当遇到重复的时候,不用从下一个字符开始搜索。举个栗子:

    abcdefdh

      高亮的是目前处理到的最长不重复子串,现在处理到d的时候,发现了重复,此时我们没有必要从b 开始重新搜索,而是算出两个d 之间有多少字符,这些字符可以组成新的不重复子串参与到下一次搜索中,这里我们有ef 两个字符,加上新来的d,就是3个字符,这个很好算:通过两个d 的id相减就可以了(6-3=3)

    这里我遇到的问题是,怎么在新的一轮搜索中更新hash表的内容,因为新的最长不重复子串是efd,前面的abcd就应该从hash表中移除。但是移除操作本身是O(n)的,没法做到O(1)。。。于是就陷进去了。

      最后看了答案,发现思路是很相似的,怎么解决我上面遇到的问题呢?就是维护“最后出现位置”的机制,这样我们就不用去纠结怎么把hash表里的东西删掉了,只用每次都更新hash表里对应字符的id。接着上面的栗子说:

    当遇到第二个d 的时候,我们不仅检查d 是否在hash表中,而且还要检查当前index(6)减去目前最长不重复子串长度(3)是否小于等于d 在hash 表中对应的id(3) 这里:6-3 <= 3 就说明上一个d确实包含在当前的最长不重复子串中。

    说的有点糊涂。。直接看代码可能还清晰点:

    int lengthOfLongestSubstring(string s) {
        int n = (int)s.size();
        if (!n) return 0;
        int len = 0, max = 0;
        unordered_map<char, int> map;
        
        for (int i = 0; i < n; i++) {
            if (map.find(s[i]) == map.end() || map[s[i]] < i - len) {
                len++;
            }
            else {
                if (len > max) { max = len; }
                len = i - map[s[i]];
            }
            map[s[i]] = i;
        }
        return len > max ? len : max;
    }

    O(n^2)的解法:

    int lengthOfLongestSubstring(string s) {
        if (!s.size()) return 0;
        int len = 0;
        int max = 0;
        unordered_map<char, int>set;
        
        for (int i = 0; i < s.size(); i++) {
            if (s.size()-i-1 < max) break;
            for (int j = i; j < s.size(); j++) {
                if (set.find(s[j]) == set.end()) {
                    len++;
                    set[s[j]] = j;
                }
                else {
                    i = set[s[j]];
                    break;
                }
            }
            if (len > max) {
                max = len;
            }
            set.clear();
            len = 0;
        }
        
        return max;
    }
    O(n^2)
  • 相关阅读:
    大数计算问题
    句子逆序
    字符个数统计
    提取不重复的整数
    合并表记录
    浅谈之高级查询over(partition by)
    proc之建表添加数据报错解决
    浅谈之过滤条件【or】
    浅谈之索引失效
    浅谈之表连接方法
  • 原文地址:https://www.cnblogs.com/agentgamer/p/4116432.html
Copyright © 2011-2022 走看看