JS刷题!双指针5-最小替换子串长度

140 阅读3分钟

1. 题目来源

稀土掘金-双指针No.41-最小替换子串长度(中等) - MarsCode

2. 解题思路

题目要求:找到一个最小的子串长度,通过替换其中的字符,使得字符串中ASDF这四个字符的频次相等。

  1. 频次统计:遍历每个字符可能出现的次数
  2. 目标统计:计算每个字符应该出现的次数
  3. 滑动窗口统计:使用两个指针 left 和 right 来表示当前窗口的范围,通过移动指针来调整窗口的氛围,通过移动指针来调整窗口的字符频次,直到找到满足条件的最小子串

3. 题解

function solution(input) {
  // 初始化 A、S、D、F 四个字符的计数为 0
  let countA = 0, countS = 0, countD = 0, countF = 0;
  
  // 统计输入字符串中每个字符的出现次数
  for (let char of input) {
    if (char === 'A') countA++;
    else if (char === 'S') countS++;
    else if (char === 'D') countD++;
    else if (char === 'F') countF++;
  }

  // 计算每个字符在理想情况下应该出现的次数(输入字符串长度的四分之一)
  const targetCount = input.length / 4;

  // 如果已经满足每个字符出现次数相等的条件,直接返回 0
  if (countA === targetCount && countS === targetCount && countD === targetCount && countF === targetCount) {
    return 0;
  }

  // 初始化滑动窗口的左右指针
  let left = 0, right = 0;
  // 最小长度初始化为输入字符串的长度
  let minLength = input.length;
  // 计算每个字符超出目标次数的剩余数量
  let surplusA = countA - targetCount, surplusS = countS - targetCount, surplusD = countD - targetCount, surplusF = countF - targetCount;

  // 滑动窗口的主逻辑
  while (right < input.length) {
    // 当右指针右移时,更新当前窗口内的字符频次
    if (input[right] === 'A') surplusA--;
    else if (input[right] === 'S') surplusS--;
    else if (input[right] === 'D') surplusD--;        
    else if (input[right] === 'F') surplusF--;

    // 当当前窗口内的字符频次满足条件时
    while (surplusA <= 0 && surplusS <= 0 && surplusD <= 0 && surplusF <= 0) {
      // 更新最小长度,取当前最小长度和当前窗口长度的较小值
      minLength = Math.min(minLength, right - left + 1);
      
      // 移动左指针,更新窗口外的字符频次
      if (input[left] === 'A') surplusA++;
      else if (input[left] === 'B') surplusS++;
      else if (input[left] === 'D') surplusD++;
      else if (input[left] === 'F') surplusF++;
      left++;
    }
    right++;
  }
  return minLength;
}

function main() {
    // 测试 solution 函数,判断 solution("ADDF") 的结果是否等于 1
    console.log(solution("ADDF") === 1);
    // 测试 solution 函数,判断 solution("ASAFASAFADDD") 的结果是否等于 3
    console.log(solution("ASAFASAFADDD") === 3);
    // 测试 solution 函数,判断 solution("SSDDFFFFAAAS") 的结果是否等于 1
    console.log(solution("SSDDFFFFAAAS") === 1);
    // 测试 solution 函数,判断 solution("AAAASSSSDDDDFFFF") 的结果是否等于 0
    console.log(solution("AAAASSSSDDDDFFFF") === 0);
    // 测试 solution 函数,判断 solution("AAAADDDDAAAASSSS") 的结果是否等于 4
    console.log(solution("AAAADDDDAAAASSSS") === 4);
}

main();

4. 关于豆包MarsCode

4.1 推荐使用!

豆包MarsCode简单方便,上手快,能应对日常的编程任务,刷题时也能给你提供不错的解题思路和示例代码,很适合新手和老手,大大提高了工作效率;所以个人挺推荐使用豆包MarsCode去辅助开发!

4.2 HowieCong与MarsCode的经历

  1. 线上参加过两次的字节跳动 X 豆包MarsCode的青训营,积极参与其中,搭配着MarsCode去刷算法题和项目开发真能学到很多

  2. 线下在参加Pycon China 2024上海站时看到了MarsCode参展,MarsCode团队成员非常热情的,拿到了MarsCode的一些周边

❓其他

1. 疑问与作者HowieCong声明

  • 如有疑问、出错的知识,请及时点击下方链接添加作者HowieCong的其中一种联系方式或发送邮件到下方邮箱告知作者HowieCong

  • 若想让作者更新哪些方面的技术文章或补充更多知识在这篇文章,请及时点击下方链接添加里面其中一种联系方式或发送邮件到下方邮箱告知作者HowieCong

  • 声明:作者HowieCong目前只是一个前端开发小菜鸟,写文章的初衷只是全面提高自身能力和见识;如果对此篇文章喜欢或能帮助到你,麻烦给作者HowieCong点个关注/给这篇文章点个赞/收藏这篇文章/在评论区留下你的想法吧,欢迎大家来交流!

2. 作者社交媒体/邮箱-HowieCong