- 浏览: 137650 次
文章分类
- 全部博客 (189)
- Tree (14)
- Dynamic Programming (34)
- Array (20)
- Search (1)
- Hash (12)
- Backtracking (22)
- Divide and Conque (8)
- Greedy (6)
- Stack (12)
- software (0)
- List (7)
- Math (22)
- Two pointers (16)
- String (20)
- Linux (1)
- Sliding Window (4)
- Finite State Machine (1)
- Breadth-first Search (7)
- Graph (4)
- DFS (6)
- BFS (3)
- Sort (9)
- 基础概念 (2)
- 沟通表达 (0)
- Heap (2)
- Binary Search (15)
- 小结 (1)
- Bit Manipulation (8)
- Union Find (4)
- Topological Sort (1)
- PriorityQueue (1)
- Design Pattern (1)
- Design (1)
- Iterator (1)
- Queue (1)
最新评论
-
likesky3:
看了数据结构书得知并不是迭代和递归的区别,yb君的写法的效果是 ...
Leetcode - Graph Valid Tree -
likesky3:
迭代和递归的区别吧~
Leetcode - Graph Valid Tree -
qb_2008:
还有一种find写法:int find(int p) { i ...
Leetcode - Graph Valid Tree -
qb_2008:
要看懂这些技巧的代码确实比较困难。我是这么看懂的:1. 明白这 ...
Leetcode - Single Num II -
qb_2008:
public int singleNumber2(int[] ...
Leetcode - Single Num II
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.
[分析] 滑动窗口法,窗口内始终仅保留至多两个相异字符组成的字符串。实现时有两个问题需要考虑:1)何时更新窗口的左边界 2)如何更新窗口的左边界。问题1简单,当前字符不在窗口内且窗口内已包含两种字符。问题2最关键,想清楚了该问题也就解决了。当前窗口的左边界字符必然是要被删除的,但需要全部清除窗口内所有该字符吗?不见得,考虑这个例子abaccc, 遍历到第一个c时若将a全部清除则求得的长度是3,但实际上应该是4。正确的做法是找到窗口内最后位置最靠左的字符,设其最末位置为mostLeftEndPos, 窗口的新左边界则为mostLeftEndPos + 1, 这种做法的正确性在于保证更新时清除的字符串最短。
参考博客中还给出了扩展题,至多保留K个相异字符。更多请阅读原文:
http://blog.csdn.net/whuwangyi/article/details/42451289
>>>第二次做
思路1:基本思想仍然是两指针式滑动窗口,实现上稍有差异。维护一个哈希表idxMap, key是字符,value是key最后出现的下标。activeTwo数组中两元素表示当前窗口中的两个相异字符。遍历字符串时若遇到新字符,意外着activeTwo中有个字符要被淘汰出窗口了,该淘汰哪个呢?易知当前位置的前一个字符应该是幸运儿,那么自然的另一个就是要被淘汰的。更新窗口前计算当前窗口长度并更新maxLen,然后更新窗口左指针为被淘汰字符最后出现下标的下一个位置。
思路2: 参考https://leetcode.com/discuss/21929/share-my-c-solution
代码清晰简洁,同longestK的差异在于使用数组代替HashMap。
注意当哈希表key是字符时使用数组代替HashMap,运行效率会稍高些。
For example, Given s = “eceba”,
T is "ece" which its length is 3.
[分析] 滑动窗口法,窗口内始终仅保留至多两个相异字符组成的字符串。实现时有两个问题需要考虑:1)何时更新窗口的左边界 2)如何更新窗口的左边界。问题1简单,当前字符不在窗口内且窗口内已包含两种字符。问题2最关键,想清楚了该问题也就解决了。当前窗口的左边界字符必然是要被删除的,但需要全部清除窗口内所有该字符吗?不见得,考虑这个例子abaccc, 遍历到第一个c时若将a全部清除则求得的长度是3,但实际上应该是4。正确的做法是找到窗口内最后位置最靠左的字符,设其最末位置为mostLeftEndPos, 窗口的新左边界则为mostLeftEndPos + 1, 这种做法的正确性在于保证更新时清除的字符串最短。
参考博客中还给出了扩展题,至多保留K个相异字符。更多请阅读原文:
http://blog.csdn.net/whuwangyi/article/details/42451289
>>>第二次做
思路1:基本思想仍然是两指针式滑动窗口,实现上稍有差异。维护一个哈希表idxMap, key是字符,value是key最后出现的下标。activeTwo数组中两元素表示当前窗口中的两个相异字符。遍历字符串时若遇到新字符,意外着activeTwo中有个字符要被淘汰出窗口了,该淘汰哪个呢?易知当前位置的前一个字符应该是幸运儿,那么自然的另一个就是要被淘汰的。更新窗口前计算当前窗口长度并更新maxLen,然后更新窗口左指针为被淘汰字符最后出现下标的下一个位置。
思路2: 参考https://leetcode.com/discuss/21929/share-my-c-solution
代码清晰简洁,同longestK的差异在于使用数组代替HashMap。
注意当哈希表key是字符时使用数组代替HashMap,运行效率会稍高些。
// 第二次做的两种实现方式 // Method 2: map中value是count时, 这种从窗口起始位置开始遍历寻找第一个被淘汰的字符方式扩展性好些,可扩展到保留k个不同的情况 public int lengthOfLongestSubstringTwoDistinct2(String s) { if (s == null) return 0; int maxDiffChars = 2; int maxLen = 0; int[] map = new int[256]; // key: char, value: occurs of key int i = 0, j = 0; // i & j is the start and end of the sliding window int count = 0; // number of diff char in the sliding window while (j < s.length()) { char curr = s.charAt(j); map[curr]++; if (map[curr] == 1) { // a new char count++; while (count > maxDiffChars) { map[s.charAt(i)]--; if (map[s.charAt(i)] == 0) count--; i++; } } maxLen = Math.max(maxLen, j - i + 1); j++; } return maxLen; } // Method 1: map中value是key最后一次出现的下标,下面的实现方式不能方便地扩展到窗口可保留最多k个字符的情况 public int lengthOfLongestSubstringTwoDistinct1(String s) { if (s == null) return 0; if (s.length() < 3) return s.length(); int[] idxMap = new int[256]; for (int i = 0; i < 256; i++) idxMap[i] = -1; char[] activeTwo = new char[2]; activeTwo[0] = s.charAt(0); int i = 0, j = 1; while (j < s.length() && s.charAt(j) == activeTwo[0]) j++; if (j == s.length()) return s.length(); activeTwo[1] = s.charAt(j); idxMap[activeTwo[0]] = j - 1; idxMap[activeTwo[1]] = j; j++; char survivor; int len = 1, maxLen = j; while (j < s.length()) { char curr = s.charAt(j); if (curr == activeTwo[0]) { idxMap[activeTwo[0]] = j; } else if (curr == activeTwo[1]) { idxMap[activeTwo[1]] = j; } else { survivor = s.charAt(j - 1); len = j - i; maxLen = Math.max(len, maxLen); if (activeTwo[0] == survivor) { i = idxMap[activeTwo[1]] + 1; activeTwo[1] = curr; idxMap[activeTwo[1]] = j; } else { i = idxMap[activeTwo[0]] + 1; activeTwo[0] = curr; idxMap[activeTwo[0]] = j; } } j++; } maxLen = Math.max(maxLen, j - i); return maxLen; }
public class LongestSubstringWithAtMost2DistinctChars { @Test public void testSolution() { Solution obj = new Solution(); Assert.assertEquals(4, obj.longest2("abaa")); Assert.assertEquals(4, obj.longest2("abaccc")); Assert.assertEquals(4, obj.longestK("abaa", 2)); Assert.assertEquals(4, obj.longestK("abaccc", 2)); Assert.assertEquals(6, obj.longestK("abacccd", 3)); } } class Solution { public int longest2(String s) { if (s == null || s.length() == 0) return 0; int start = 0; int N = s.length(); HashMap<Character, Integer> map = new HashMap<Character, Integer>(2); map.put(s.charAt(0), 0); int max = 1; for (int i = 1; i < N; i++) { char c = s.charAt(i); if (!map.containsKey(c) && map.size() == 2) { // update left bound of sliding window int mostLeftEndPos = i - 1; char toBeRemoved = ' '; for (Character key : map.keySet()) { if (map.get(key) < mostLeftEndPos) { mostLeftEndPos = map.get(key); toBeRemoved = key; } } start = mostLeftEndPos + 1; map.remove(toBeRemoved); } map.put(c, i); max = Math.max(max, i - start + 1); } return max; } //k 比较大时遍历map就比较低效,不如从start开始寻找第一个最后位置跑出窗口的字符 public int longestK(String s, int k) { if (s == null || s.length() == 0) return 0; int N = s.length(); int start = 0; int max = 0; // c: letter; value: the number of occurrences. HashMap<Character, Integer> map = new HashMap<Character, Integer>(); for (int i = 0; i < N; i++) { char c = s.charAt(i); if (map.containsKey(c)) { map.put(c, map.get(c) + 1); } else { map.put(c, 1); while (map.size() > k) { char startChar = s.charAt(start++); int count = map.get(startChar); if (count > 1) { map.put(c, count - 1); } else { map.remove(startChar); } } } max = Math.max(max, i - start + 1); } return max; } }
发表评论
-
Leetcode - 3Sum Smaller
2015-08-18 22:12 1490Given an array of n integers nu ... -
Leetcode - Remove Nth Node From End of List
2015-07-27 21:09 464Remove Nth Node From End of Lis ... -
Leetcode - Remove Elements
2015-07-27 10:19 447Given an array and a value, rem ... -
Leetcode - Sliding Window Maximum
2015-07-23 09:18 563Given an array nums, there is a ... -
Leetcode - Minimum Size Subarray Sum
2015-07-22 21:01 762Given an array of n positive in ... -
Leetcode - LinedListCycleII
2015-07-22 10:18 560Given a linked list, return the ... -
Leetcode - Partition List
2015-07-22 09:09 411Given a linked list and a value ... -
Leetcode - 4Sum
2015-07-21 07:25 474Given an array S of n integers, ... -
Leetcode - 3Sum Closest
2015-07-20 22:09 509Given an array S of n integers, ... -
Leetcode - 3 Sum
2015-07-20 21:11 494Given an array S of n integers, ... -
Leetcode - Container With Most Water
2015-07-20 09:55 412Given n non-negative integers a ... -
Leetcode - Trapping Rain Water
2015-07-20 09:26 445Given n non-negative integers r ... -
Leetcode - Sort Colors
2015-07-17 10:04 402Given an array with n objects c ... -
Leetcode - Substring with Contentaion of All Words
2015-06-18 10:01 511You are given a string, s, and ... -
Leetcode - Minimum Window String
2015-06-14 19:33 577Given a string S and a string T ... -
Leetcode - Minumum Size Subarray Sum
2015-06-09 10:11 397Given an array of n positive ...
相关推荐
java java_leetcode题解之Longest Substring with At Most Two Distinct
javascript js_leetcode题解之159-longest-substring-with-at-most-two-distinct
c语言入门 c语言_leetcode题解03-longest-substring-without-repeating-characters
js js_leetcode题解3-longest-substring-without-repeating-characters.js
答案LeetCode-Longest_Substring_Without_Repeating_Characters 这是LeetCode上“最长子串无重复字符”问题的解决方案。 问题描述:给定一个字符串,求没有重复字符的最长子串的长度。 示例 1:输入:“abcabcbb” ...
c语言入门 c语言_leetcode题解05-longest-palindromic-substring.c
c c语言_leetcode 0003_longest_substring_without_repeat.zip
c c语言_leetcode 0005_longest_palindromic_substring.zip
java java_leetcode-115-distinct-subsquences
Given a string, find the length of the longest substring without repeating characters. Examples: Given "abcabcbb", the answer is "abc", which the length is 3. Given "bbbbb", the answer is "b", with...
c c语言_leetcode 0030_substring_with_concatenation_of_all_words.zip
js js_leetcode题解之5-longest-palindromic-substring.js
《在IDE中高效进行LeetCode练习:leetcode-editor的深度解析》 在编程学习与技能提升的过程中,LeetCode作为一款广受欢迎的在线编程挑战平台,帮助众多开发者锻炼算法思维,提高编程能力。而为了进一步提升练习体验...
leetcode-习题集资源leetcode-习题集资源leetcode-习题集资源leetcode-习题集资源leetcode-习题集资源leetcode-习题集资源
leetcode-cli-plugins leetcode-cli 的第 3 方插件。 什么是 如何使用 如何使用 插件 名称 描述 增强的命令 按公司或标签过滤问题 list 不要在同一台计算机上使 Chrome 的会话过期 login 不要在同一台计算机上使 ...
在IDE中解决LeetCode问题,支持leetcode.com与leetcode-cn.com,满足基本的做题需求。 理论上支持: IntelliJ IDEA PhpStorm WebStorm PyCharm RubyMine AppCode CLion GoLand DataGrip Rider MPS Android Studio。
LeetCode Editor 7.4 版本的下载是一个名为 "leetcode-editor" 的压缩包文件。这个压缩包的导入过程非常简单,只需要将它直接拖入 IDEA 界面,IDEA 会自动识别并安装插件。这种方式使得安装过程无需额外的步骤,对于...
leetcode-习题集资源源代码leetcode-习题集资源源代码leetcode-习题集资源源代码leetcode-习题集资源源代码leetcode-习题集资源源代码
~/.vscode/extensions/leetcode.vscode-leetcode-0.17.0/node_modules/vsc-leetcode-cli/bin/leetcode /usr/local/bin/leetcode 修改模板 open ~/.vscode/extensions/leetcode.vscode-leetcode-0.17.0/node_modules/...