JS算法-字符串至多包含 K 个不同字符的最长子串

506 阅读1分钟

本题来自leetcode第 340 题和第 159 题,难度中等。

题目介绍

给定一个字符串 s ,找出 至多 包含 k 个不同字符的最长子串 T(第340题)。

示例 1:

输入: s = "eceba", k = 2
输出: 3
解释: 则 T 为 "ece",所以长度为 3。

示例 2:

输入: s = "aa", k = 1
输出: 2
解释: 则 T 为 "aa",所以长度为 2。

解题思路

本题可以利用双指针滑动窗口的思想解决

  • 开始时,左指针不动,右指针开始向右移动
  • 将每个不同的字符都存到字典中,key为字符,value为出现的次数,再次出现该字符对应的value加1
  • 当左右指针形成的窗口中出现的不同字符的个数超过k个时,右指针停止,左指针开始从左到右滑动
  • 当左指针滑动时,当前字符出现的次数减1,直到窗口中不同字符的个数变为k
  • 接着右指针继续滑动,,直到右指针滑动到最后

代码演示

/**
 * @param {string} s
 * @param {number} k
 * @return {number}
 */
var lengthOfLongestSubstringKDistinct = function(s, k) {
    let l = 0, ans = 0;
    const map = new Map();
    const len = s.length;
    for(let i = 0; i < len; i++) {
      let c = s[i];
      if(map.get(c)) {
        map.set(c, map.get(c) + 1);
      } else {
        map.set(c, 1);
      }
      while (map.size > k) {
        let ch = s[l];
        map.set(ch, map.get(ch) - 1);
        if (map.get(ch) === 0) {
          map.delete(ch);
        }
        l++;
      }
      ans = Math.max(ans, i - l + 1);
    }
    return ans;
};

相似题目

给定一个字符串 s ,找出 至多 包含两个不同字符的最长子串 t ,并返回该子串的长度。(第159题)

总结

leetcode第三题的升级版,需要好好消化吸收一下,这类问题差不多就可以应对了。