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;
}
}

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

  1. [LeetCode#246] Missing Ranges Strobogrammatic Number

    Problem: A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked a ...

  2. LeetCode 163. Missing Ranges (缺失的区间)$

    Given a sorted integer array where the range of elements are in the inclusive range [lower, upper], ...

  3. [LeetCode#163] Missing Ranges

    Problem: Given a sorted integer array where the range of elements are [lower, upper] inclusive, retu ...

  4. [leetcode]163. Missing Ranges缺失范围

    Given a sorted integer array nums, where the range of elements are in the inclusive range [lower, up ...

  5. [LeetCode] 163. Missing Ranges 缺失区间

    Given a sorted integer array nums, where the range of elements are in the inclusive range [lower, up ...

  6. ✡ leetcode 163. Missing Ranges 找出缺失范围 --------- java

    Given a sorted integer array where the range of elements are in the inclusive range [lower, upper], ...

  7. 【LeetCode】Missing Ranges

    Missing Ranges Given a sorted integer array where the range of elements are [lower, upper] inclusive ...

  8. [LeetCode] 228. Summary Ranges 总结区间

    Given a sorted integer array without duplicates, return the summary of its ranges. Example 1: Input: ...

  9. [LeetCode] Strobogrammatic Number III 对称数之三

    A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside ...

随机推荐

  1. 码表 Unicode GBK UTF8 示例

    Unicode的编码形式与对应的字符串相互转换 /**  * Unicode的编码形式与对应的字符串相互转换  * @author 白乾涛  */ public class UnicodeUtils  ...

  2. 推断类型var

    1.为什么使用推断类型var var可以根据变量的初始值自动推断局部变量类型,当无法确定所用变量的具体类型时可使用var 2.如何使用推断类型var 客户端代码 static void Main(st ...

  3. Android开发必备:颜色选择

      AA 指定透明度. 00 是完全透明. FF 是完全不透明.超出取值范围的值将被恢复为默认值.    ffff00 ffff33 ffff66 ffff99 ffffcc ffffff ffcc0 ...

  4. wordpress 后台显示空白现象

    简单的说两句,出现此种现象的因素可能在于主题或者插件再或者是因为(恶意)插件(误更改)更改了某个重要的文件出现错误.本次我遇到的是插件的错误,具体是什么错误,我也没有去深究,重要的是结果! 使用排查的 ...

  5. 如何快速的将Centos6.7快速升级3.10.9

    参考文档:http://www.xiexianbin.cn/linux/2015/10/15/quickly-upgrade-centos6.5-kernel-from-2.6.32-to-3.10. ...

  6. winform中的chat

    百度一下 源代码下载:百度一下

  7. 2014年11月17号------html起始

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. POJ 1631 Bridging signals(LIS O(nlogn)算法)

    Bridging signals Description 'Oh no, they've done it again', cries the chief designer at the Waferla ...

  9. php练习——打印半金字塔、金字塔、空心金字塔、菱形、空心菱形

    半金字塔 金字塔 空心金字塔 菱形     空心菱形

  10. UML2.0统一建模语言

      Unified Modeling Language (UML)又称统一建模语言或标准建模语言,是支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持,包括由需求分析到规 ...