算法12,滑动窗口,将x减到0的最小操作数

复制代码
 public int minOperations(int[] nums, int x) {
             int left = 0,right = 0,n=nums.length,sum1=0,sum=0,len=-1;
      for(int i=0;i<n;i++){
          sum1+=nums[i];
      }
      int target=sum1-x;
      if(target<0){
          return -1;
      }
      for(;right<n;right++) {
          sum += nums[right];
          while (sum > target) {
              sum -= nums[left++];//记得++
          }
          if (sum == target) {
              len = Math.max(len, right - left + 1);
          }
      }
      if(len==-1)return -1;
      else return n-len;
    }

要解决"滑动窗口最大连续1的个数"问题,我们可以通过滑动窗口(双指针) 思路高效求解,核心是在遍历中维护一个包含不超过k个0的窗口,并记录窗口的最大长度。

问题分析

给定二进制数组 nums和整数 k,允许翻转最多k个0为1 ,求翻转后最长连续1的长度。等价于:找到一个子数组,其中0的数量≤k,且该子数组长度最大(因为翻转后0全变1,子数组长度即为连续1的长度)。

解题思路(滑动窗口)

用左右指针 维护一个动态窗口 [left, right],并统计窗口内0的数量 count:

  1. 右指针扩张 :遍历数组,右指针right逐个向右移动,若遇到0则count加1(记录窗口内0的数量)。

  2. 左指针收缩 :当窗口内0的数量count超过k时,右移左指针left,直到count ≤ k(过程中若左指针指向0,则count减1)。

  3. 更新最大长度 :每次窗口稳定后(即count ≤ k时),计算当前窗口长度 right - left + 1,并更新全局最大长度。

代码实现(Java)

复制代码
public class Solution {
    public int longestOnes(int[] nums, int k) {
        int left = 0;      // 左指针,窗口左边界
        int count = 0;     // 窗口内0的数量
        int maxLen = 0;    // 记录最大连续1的长度
        
        for (int right = 0; right < nums.length; right++) {  // 右指针遍历数组
            if (nums[right] == 0) {
                count++;  // 遇到0,窗口内0的数量+1
            }
            
            // 若0的数量超过k,左指针收缩窗口,直到0的数量≤k
            while (count > k) {
                if (nums[left] == 0) {
                    count--;  // 左指针指向0,移出窗口后0的数量-1
                }
                left++;  // 左指针右移,缩小窗口
            }
            
            // 计算当前窗口长度,更新最大长度
            maxLen = Math.max(maxLen, right - left + 1);
        }
        
        return maxLen;
    }
}

代码解释

  • 初始化变量 :left为窗口左边界,count统计窗口内0的数量,maxLen记录最长有效子数组长度。

  • 右指针遍历 :right从0开始遍历数组,遇到0时count加1。

  • 左指针收缩 :当count > k时,循环右移left,若left指向0则count减1(因为该0被移出窗口),直到count ≤ k。

  • 更新最大长度 :每次窗口调整后,计算当前窗口长度 right - left + 1,并与maxLen比较,保留更大值。

复杂度分析

  • 时间复杂度:O(n),其中n为数组长度。左右指针各遍历数组一次,整体为线性时间。

  • 空间复杂度:O(1),仅使用常数额外空间。

该方法通过滑动窗口动态维护有效区间,在一次遍历中完成所有操作,保证了效率与简洁性。

相关推荐
liliangcsdn20 分钟前
派息率指标的应用探索和分析
大数据·算法
for_ever_love__20 分钟前
MySQL 全文索引实战:FULLTEXT、ngram 中文分词与 MATCH AGAINST 到底该怎么用
java·python·mysql·全文检索·分词·索引·ngram
java资料站24 分钟前
五、Spring AI Alibaba · Memory · Saver(短期会话)
java·spring·microsoft
垆边人似月.42 分钟前
华为机试题 :两数之和
c++·算法·华为
默默开发43 分钟前
物流行业可用算法方向
算法
垆边人似月.1 小时前
华为机试题 :有效的括号
c++·算法·华为
夜之眷属1 小时前
Core dump 崩溃排查:JVM 宕机后,那份 core 文件怎么用 gdb 还原现场
java·运维·服务器·jvm
波加曼大王1 小时前
# vLLM不要迷信PagedAttention神话,聊聊线上藏着的内部碎片陷阱
java·架构
SL_staff1 小时前
目标健康度自检清单:开发者视角下的目标-计划-任务链路断点诊断
java·开源·github
A加ITIL教练长河achotsao1 小时前
ITIL Master 战略领导者课后系列分享:AI编程正在重新划分研发与运维的边界
算法