[抄题]:
给定一个字符串,找到最多有k个不同字符的最长子字符串。eg:eceba, k = 3, return eceb
[暴力解法]:
时间分析:
空间分析:
[思维问题]:
- 怎么想到两根指针的:从双层for循环的优化 开始分析
[一句话思路]:
[输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):
[画图]:
[一刷]:
- 没有养成好习惯:退出条件写在添加条件之前。因此先判断if (map.size() == k),再map.put(c,1)
[二刷]:
- 没有养成好习惯:循环过后更新max,循环过后移动指针j,都要在循环之前就写好
[三刷]:
[四刷]:
[五刷]:
[五分钟肉眼debug的结果]:
[总结]:
[复杂度]:Time complexity: O(2n) Space complexity: O(n)
[英文数据结构或算法,为什么不用别的数据结构或算法]:
- 字符串中的字母用256[]存比较方便,但是用hashmap存也可以,相同的字母放在一个盒子里,盒子个数达到k时就退出
- 而且hashmap中还有.size()取总长度 .remove()去除key,城会玩 头一次见
[关键模板化代码]:
j用的是while循环,因为第二层不是for,for的特点是必须要从0开始
[其他解法]:
[Follow Up]:
[LC给出的题目变变变]:
k = 2
[代码风格] :
hashmap判断有没有key不是用contains,而是用containsKey,没怎么注意
public class Solution { /** * @param s : A string * @return : The length of the longest substring * that contains at most k distinct characters. */ public int lengthOfLongestSubstringKDistinct(String s, int k) { //corner case int maxLen = 0; HashMap<Character,Integer> map = new HashMap<>(); if (k > s.length()) { return 0; } int i = 0, j = 0; //i, j go in the same direction for (i = 0; i < s.length(); i++) { //put j into hashmap while (j < s.length()) { char c = s.charAt(j); if (map.containsKey(c)) { map.put(c, map.get(c) + 1); }else { if (map.size() == k) { break; }else { map.put(c, 1); } } //pointers move first j++; } //renew ans first maxLen = Math.max(max, j - i); //remove i if exists char c = s.charAt(i); if (map.containsKey(c)) { int count = map.get(c); if (count > 1) { map.put(c, count - 1); }else { map.remove(c); } } } return maxLen; } }