[LeetCode#159] Missing Ranges Strobogrammatic Number

Problem:

Given a string, find the length of the longest substring T that contains at most 2 distinct characters.

For example, Given s = “eceba”,

T is "ece" which its length is 3.

Analysis:

This is a very very typical question in using slide window. Why?
The problem asks the substring to meet certain characteristic. The substring means the target must be a series of succsive characters. 

Basic idea:
The problem restricts the target must contain no more than 2 distinct characters.
Apparently we should use a HashMap to record such information. (when there is a quantitive restriction, you should firstly think about using HashMap rather than HashSet)

Weaving Picature:
Maintain two boundary for a window : "front" and "end", recording the relevent information(according problems‘ requirement and restriction) through a HashMap. 

For this problem, we maintain "HashMap<Character, Integer>" to record Character‘s count in the window. It means we at most allow two distinct Characters in the HashMap. When the end pointer was moved onto a new character.
case1. iff the charcter existed in the HashMap, we can directly include it into our current window.
case2. iff the charcter is not existed in the HashMap, we may have to adjust the start pointer of slide window to make it is valid to add the new charcter into the window.
Note: you should not hesitate over wheather to use hashmap‘s size() or "hashmap.contains(c)" as the first level "if-else" checking. Since we may not need to care the hashmap‘s size when case1.
---------------------------------------------------------------------
if (!map.containsKey(c)) {
    ...
}else {
    ...
}

For case 2.
a. Iff the map‘s size is less than 2, we can directly include it into window.
if (map.size() < 2) {
    map.put(c, 1);
    end = i;
}

b. Iff the map‘s size is equal to 2, we need to adjust the window‘s start boundary.
Skill: keep on moving start boundary, until one character was totally wiped out from the window.
while (map.size() == 2) {
    char discard = s.charAt(start);
    start++;
    map.put(discard, map.get(discard) - 1);
    if (map.get(discard) == 0)
        map.remove(discard);
}
map.put(c, 1);
end = i;
Note: we don‘t need to care wheather "start" would exceed the s.length, since when there is only one character in the window, it would exit the while loop. This is beautiful part in using while-loop in slide window.

Solution 1:

public class Solution {
    public int lengthOfLongestSubstringTwoDistinct(String s) {
        if (s == null)
            throw new IllegalArgumentException("s is null");
        int len = s.length();
        if (len <= 2)
            return len;
        int start = 0, end = 0, max = 0;
        HashMap<Character, Integer> map = new HashMap<Character, Integer> ();
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            if (!map.containsKey(c)) {
                if (map.size() < 2) {
                    map.put(c, 1);
                    end = i;
                } else{
                    while (map.size() == 2) {
                        char discard = s.charAt(start);
                        start++;
                        map.put(discard, map.get(discard) - 1);
                        if (map.get(discard) == 0)
                            map.remove(discard);
                    }
                    map.put(c, 1);
                    end = i;
                }
            } else{
                map.put(c, map.get(c) + 1);
                end = i;
            }
            max = Math.max(max, end - start + 1);
        }
        return max;
    }
}

Improvement Analysis:

Even my first solution is right, there are many room for improving it regarding the elegance of code.
1. When we use slide window, "i" is actually the end boundary of slide window. We don‘t need to maintain a end variable. And we always measure the window, after it was adjusted into valid. (i is not change!)
max = Math.max(max, i - start + 1);

2. The purpose of adjusting window is to make the current end boundary valid. And after the adjust (or no need for the adjust), we finally need to put the character at "end" into the map.
while (map.size() == 2) {
    char discard = s.charAt(start);
    start++;
    map.put(discard, map.get(discard) - 1);
    if (map.get(discard) == 0)
        map.remove(discard);
}
map.put(c, 1);

Solution 2:

public class Solution {
    public int lengthOfLongestSubstringTwoDistinct(String s) {
        if (s == null)
            throw new IllegalArgumentException("s is null");
        int len = s.length();
        if (len <= 2)
            return len;
        int start = 0, end = 0, max = 0;
        HashMap<Character, Integer> map = new HashMap<Character, Integer> ();
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            if (!map.containsKey(c)) {
                while (map.size() == 2) {
                    char discard = s.charAt(start);
                    start++;
                    map.put(discard, map.get(discard) - 1);
                    if (map.get(discard) == 0)
                        map.remove(discard);
                }
                map.put(c, 1);
            } else{
                map.put(c, map.get(c) + 1);
            }
            max = Math.max(max, i - start + 1);
        }
        return max;
    }
}
时间: 2024-11-10 18:31:20

[LeetCode#159] Missing Ranges Strobogrammatic Number的相关文章

[LeetCode#246] Missing Ranges Strobogrammatic Number

Problem: A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down). Write a function to determine if a number is strobogrammatic. The number is represented as a string. For example, the numbers "69"

[LeetCode] 163. Missing Ranges 缺失区间

Given a sorted integer array nums, where the range of elements are in the inclusive range [lower, upper], return its missing ranges. Example: Input: nums = [0, 1, 3, 50, 75], lower = 0 and upper = 99,Output: ["2", "4->49", "51-

leetcode[163]Missing Ranges

Given a sorted integer array where the range of elements are [lower, upper] inclusive, return its missing ranges. For example, given [0, 1, 3, 50, 75], lower = 0 and upper = 99, return ["2", "4->49", "51->74", "76-

【LeetCode】Missing Ranges

Missing Ranges Given a sorted integer array where the range of elements are [lower, upper] inclusive, return its missing ranges. For example, given [0, 1, 3, 50, 75], lower = 0 and upper = 99, return ["2", "4->49", "51->74&q

LeetCode – Refresh – Missing Ranges

1 class Solution { 2 public: 3 string getRange(int start, int end) { 4 ostringstream oss; 5 if (start == end) { 6 oss << start; 7 } else { 8 oss << start << "->" << end; 9 } 10 return oss.str(); 11 } 12 vector<strin

[LeetCode] Strobogrammatic Number 对称数

A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down). Write a function to determine if a number is strobogrammatic. The number is represented as a string. For example, the numbers "69", "

[LeetCode] Missing Ranges 缺失区间

Given a sorted integer array where the range of elements are [0, 99] inclusive, return its missing ranges.For example, given [0, 1, 3, 50, 75], return [“2”, “4->49”, “51->74”, “76->99”] 这道题让我们求缺失区间,跟之前那道Summary Ranges很类似,这道题让我们求缺失的空间,给了一个空间的范围[lo

LeetCode Strobogrammatic Number II

原题链接在这里:https://leetcode.com/problems/strobogrammatic-number-ii/ 题目: A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down). Find all strobogrammatic numbers that are of length = n. For example,Given

LeetCode Strobogrammatic Number

原题链接在这里:https://leetcode.com/problems/strobogrammatic-number/ 题目: A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down). Write a function to determine if a number is strobogrammatic. The number is r