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. Hadoop 2.6.3运行自带WordCount程序笔记

    运行平台:Hadoop 2.6.3 模式:完全分布模式 1.准备统计文本,以一段文字为例:eg.txt The Project Gutenberg EBook of War and Peace, by ...

  2. [转载]SharePoint 网站管理-PowerShell

    1. 显示场中所有可用的网站集 Get-SPSite Get-SPSite 2. 显示某一Web应用程序下可用的网站集 Get-SPSite –WebApplication "SharePo ...

  3. file的name值

    在picturelibrary中取一张jpg文件, 其Name值为  "NoThumbnail.jpg",注意后面的.jpg             foreach (SPFile ...

  4. (转)apache的keepalive和keepalivetimeout(apache优化)

    KeepAlive指的是保持连接活跃,类似于Mysql的永久连接.   如果将KeepAlive设置为On,那么来自同一客户端的请求就不需要再一次连接,避免每次请求都要新建一个连接而加重服务器的负担. ...

  5. AndroidStudio字体主题样式分享

    最近慢慢在从eclipse往AndroidStudio习惯,但总觉得AS的默认字体颜色看的不舒服,便花了些时间将字体颜色样式改成了和原来类似的.以下是效果图. 这里是下载地址http://downlo ...

  6. C#当中的多线程_任务并行库(下)

    4.8 处理任务中的异常 下面这个例子讨论了任务当中抛出异常,以及任务异常的获取     class Program     {         static void Main(string[] a ...

  7. double 类型运算会出现精度问题

    要先转换为字符串,后进行运算,可以写个方法做乘法运算public static double mul(double v1,double v2){BigDecimal b1 = new BigDecim ...

  8. CI 笔记 数据库

    demo: 1.  建立数据库,driver, 字段 name,telphone,idcard,car,content 2. 建立model,Driver_model.php文件, 建立add方法, ...

  9. 系统设计 - IOS 程序插件及功能动态更新思路

    所用框架及语言 IOS客户端-Wax(开发愤怒的小鸟的连接Lua 和 Objc的框架),Lua,Objc, 服务端-Java(用于返回插件页面)        由 于Lua脚本语言,不需要编译即可运行 ...

  10. HDU_1406 完数

    Problem Description 完数的定义:如果一个大于1的正整数的所有因子之和等于它的本身,则称这个数是完数,比如6,28都是完数:6=1+2+3:28=1+2+4+7+14. 本题的任务是 ...