【力扣刷题-滑动窗口篇】2134. 最少交换次数来组合所有的 1 II的定长滑动窗口解法

【力扣刷题-滑动窗口篇】(面试原题)2134. 最少交换次数来组合所有的 1 II的定长滑动窗口解法

交换 定义为选中一个数组中的两个 互不相同 的位置并交换二者的值。

环形 数组是一个数组,可以认为 第一个 元素和 最后一个 元素 相邻

给你一个 二进制环形 数组 nums ,返回在 任意位置 将数组中的所有 1 聚集在一起需要的最少交换次数。

示例 1:

输入:nums = [0,1,0,1,1,0,0]
输出:1
解释:这里列出一些能够将所有 1 聚集在一起的方案:
[0,0,1,1,1,0,0] 交换 1 次。
[0,1,1,1,0,0,0] 交换 1 次。
[1,1,0,0,0,0,1] 交换 2 次(利用数组的环形特性)。
无法在交换 0 次的情况下将数组中的所有 1 聚集在一起。
因此,需要的最少交换次数为 1 。

示例 2:

输入:nums = [0,1,1,1,0,0,1,1,0]
输出:2
解释:这里列出一些能够将所有 1 聚集在一起的方案:
[1,1,1,0,0,0,0,1,1] 交换 2 次(利用数组的环形特性)。
[1,1,1,1,1,0,0,0,0] 交换 2 次。
无法在交换 0 次或 1 次的情况下将数组中的所有 1 聚集在一起。
因此,需要的最少交换次数为 2 。

示例 3:

输入:nums = [1,1,0,0,1]
输出:0
解释:得益于数组的环形特性,所有的 1 已经聚集在一起。
因此,需要的最少交换次数为 0 。

提示:

  • 1 <= nums.length <= 10^5
  • nums[i]0 或者 1

题目链接

2134. 最少交换次数来组合所有的 1 II

最优解

class Solution {
   
    public int minSwaps(int[] nums) {
   
        // 最小交换次数,实质上是数组里的1的个数的窗口内,含有0的最小个数
        int length = nums.length;
        // 统计1的个数
        int oneLength = 0;
        // 求的是定长滑动窗口里0的最小个数
        int res 
<think>好的,用户现在遇到了学习上的困难,需要我的帮助。让我仔细看看他的问。 用户提到他正在跟着力扣上的灵神学习,模仿他的代码,但灵神的解法中经常出现哈希表、mod、二进制&等符号,这让用户感到困惑,尤其是在学习滑动窗口部分时,完全不会写代码,感到挫败,甚至想哭。这让我想到,用户可能是一个刚开始学习算法的新手,对某些高级技巧和符号不熟悉,导致学习受阻。 首先,我需要确认用户的具体问。他提到的主要是符号和数据结构的问,比如哈希表、模运算、位运算等。这些在算法中确实很常见,尤其是位运算,对于新手来说可能比较陌生。另外,滑动窗口作为一种常见的算法技巧,可能在实现时涉及到这些操作,用户可能因为不理解这些部分而无法掌握滑动窗口的整体思路。 接下来,我需要分析用户的潜在需求。用户可能希望了解这些符号的含义以及它们在算法中的应用,同时需要指导如何有效学习滑动窗口这类算法,克服当前的困难。此外,用户可能还希望获得一些学习策略或资源,帮助他逐步提升,而不是被复杂的代码吓倒。 我需要考虑如何组织回答。首先应该共情,肯定用户的感受,避免让他觉得自己笨。然后分点解释那些让他困惑的符号和概念,比如哈希表、mod、位运算,用简单的例子说明它们在算法中的作用。接着,针对滑动窗口,给出一个基础的模板或示例,帮助他理解基本结构,再逐步引入这些高级技巧。最后,提供学习建议,比如从基础开始,拆解问,刻意练习等,鼓励他坚持下去。 同时,要注意避免使用过于专业的术语,用通俗易懂的语言,结合具体例子,让用户能够逐步理解。比如,解释位运算时,可以用与运算来判断奇偶,或者用异或来交换变量,这样用户能直观看到这些操作的实际应用。 还需要提醒用户不要急于比较他人,每个人的学习节奏不同,掌握正确的学习方法和持续练习是关键。可能用户看到灵神的代码高效简洁,但自己无法立即掌握,这时候需要强调基础的重要性,以及分步骤学习的重要性。 总结下来,回答的结构应该是:共情 -> 解释困惑点 -> 滑动窗口的简单示例 -> 学习建议。这样既解决了用户当前的困惑,又提供了后续的学习方向,帮助他建立信心。</think>我完全理解你的焦虑,很多刚接触算法的同学都有过类似的感受。让我用最直白的方式帮你梳理问,你绝对不是笨,只是还没找到合适的学习路径。我们从这几个方面来拆解: 1. **那些让你害怕的符号其实都是工具** - `哈希表`(字典):就像快递柜,每个编号对应一个包裹。代码中用来快速查数据,比如`dict[key] = value` - `mod`(取余):比如`7%3=1`,常用于处理循环问(比如环形数组) - `二进制&`:位运算中的与操作,比如`5 & 3 = 1`(0101 & 0011 = 0001),常用于判断奇偶、权限校验 2. **滑动窗口的核心本质** 就像用放大镜在字符串/数组上移动,记住这个基础模板: ```python left = 0 for right in range(len(s)): # 处理右指针 while 窗口不满足条件: # 处理左指针 left += 1 # 更新结果 ``` 3. **学习策略建议** ① 先理解基础再学优化:比如先实现暴力解法,再学滑动窗口优化 ② 拆解复杂操作:比如遇到`sum%k == 0`,先理解模运算的数学意义 ③ 刻意练习模式识别:滑动窗口的常见特征——子数组、子串、连续区间 **举个实际例子**:力扣3.无重复字符的最长子串 基础解法: ```python def lengthOfLongestSubstring(s: str) -> int: seen = set() # 哈希集合记录已出现字符 left = 0 max_len = 0 for right in range(len(s)): while s[right] in seen: # 发现重复 seen.remove(s[left]) # 左指针右移 left += 1 seen.add(s[right]) max_len = max(max_len, right - left + 1) return max_len ``` 这个基础版本只用到了集合和双指针,完全没用到高级技巧。理解了核心逻辑后,再看灵神的各种优化技巧会更轻松。 **给初学者的建议**: 1. 先掌握每个知识点的基本形态(比如滑动窗口的标准模板) 2. 遇到不懂的符号立刻查文档(比如Python的`collections`模块文档) 3. 从简单开始培养信心(推荐先做这些:209.长度最小的子数组、643.子数组最大平均数) 4. 画图辅助理解(在纸上画出窗口移动过程) 坚持每天攻克一个小知识点,一个月后回头看会发现巨大进步。算法的学习曲线本就是先难后易,你现在经历的正是突破前的阵痛期,请一定不要放弃!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值