Leetcode - Longest Substring with At Most Two Distinct Characters

My code:

public class Solution {
    public int lengthOfLongestSubstringTwoDistinct(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }
        
        HashMap<Character, Integer> map = new HashMap<Character, Integer>();
        int i = 0;
        int j = 0;
        int maxLen = 0;
        for (; i < s.length(); i++) {
            char curr = s.charAt(i);
            if (map.containsKey(curr)) {
                map.put(curr, map.get(curr) + 1);
                maxLen = Math.max(maxLen, i - j + 1);
            }
            else {
                if (map.size() <= 1) {
                    map.put(curr, 1);
                    maxLen = Math.max(maxLen, i - j + 1);
                }
                else {
                    while (map.size() >= 2) {
                        char pre = s.charAt(j);
                        int times = map.get(pre);
                        times--;
                        if (times == 0) {
                            map.remove(pre);
                        }
                        else {
                            map.put(pre, times);
                        }
                        j++;
                    }
                    map.put(curr, 1);
                    maxLen = Math.max(maxLen, i - j + 1);
                }
            }
        }
        
        return maxLen;
    }
}

这道题目我以前竟然没有做过??
自己写了出来,感觉配不上hard的称号。
和 longest substring with no repeating characters
一样的思路。
这里,key -> character
value -> counter

每当我发现,我需要插入一个新的字母,并且这个字母使得当前窗口unique character变为3 时,我就需要开始删减窗口。
左侧的j就开始移动,然后每移动一格,将该处的character counter–
如果 counter == 0, remove key from hash table

do while until map.size() < 2
然后做插入操作。
每个元素会被访问两次。

所以时间复杂度是 O(n)
空间复杂度是 O(n)

然后看答案,感觉有种解法更快,他只需要遍历一次数组,而不是两次。

My code:

public class Solution {
    public int lengthOfLongestSubstringTwoDistinct(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }
        
        HashMap<Character, Integer> map = new HashMap<Character, Integer>();

        int maxLen = 0;
        int j = 0;
        for (int i = 0; i < s.length(); i++) {
            char curr = s.charAt(i);
            map.put(curr, i);
            if (map.size() > 2) {
                int leftMost = Integer.MAX_VALUE;
                for (Character c : map.keySet()) {
                    leftMost = Math.min(leftMost, map.get(c));
                }
                map.remove(s.charAt(leftMost));
                j = leftMost + 1;
                
            }
            maxLen = Math.max(maxLen, i - j + 1);
        }
                
        return maxLen;
    }
}

reference:
https://discuss.leetcode.com/topic/26640/simple-o-n-java-solution-easily-extend-to-k-characters

其实就是,value存的是最新的位置。
当我们发现 map.size() > 2时,将该窗口,最左侧的那个character找出来 (遍历当前map完成这个任务)
然后从hash table里面删除。
然后 j = leftMost + 1,这是新窗口的最左侧了。
然后可以更新maxLen

差不多就这个思路了。

Anyway, Good luck, Richardo! — 09/18/2016

    原文作者:Richardo92
    原文地址: https://www.jianshu.com/p/46999823b7bd#comments
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞