LeetCode 每日一题笔记 日期:2026.05.13 题目:1674. 使数组互补的最少操作次数

LeetCode 每日一题笔记

0. 前言

  • 日期:2026.05.13
  • 题目:1674. 使数组互补的最少操作次数
  • 难度:中等
  • 标签:数组、差分数组、贪心、前缀和

1. 题目理解

问题描述

给你一个长度为偶数 n 的整数数组 nums 和一个整数 limit。每次操作可以将数组中任意元素替换为 1~limit 之间的其他整数。

当数组满足 nums[i] + nums[n-1-i] 对所有 i 都等于同一个数时,数组称为互补数组

求使数组变为互补数组所需的最少操作次数

示例

输入:nums = [1,2,4,3], limit = 4

输出:1

解释:

修改 nums[2]2,数组变为 [1,2,2,3]

此时 1+3=42+2=4,所有互补对的和均为4,仅需1次操作。

2. 解题思路

核心观察

  • 互补数组的核心是:所有 (nums[i], nums[n-1-i]) 对的和必须相等,设为 x
  • 对每一对 (a, b),修改次数与目标和 x 的关系:
    • x == a + b:无需修改,操作次数 0
    • min(a,b)+1 ≤ x ≤ max(a,b)+limit:修改其中一个数即可,操作次数 1
    • 其他情况:两个数都要修改,操作次数 2
  • 利用差分数组 快速统计所有可能 x 对应的总操作次数,再取最小值。

算法步骤

  1. 初始化差分数组 diff,长度为 2*limit+2
  2. 遍历每一对互补元素 (a, b)
    • 初始所有 x 的操作次数加2;
    • cost=1 的区间 [min(a,b)+1, max(a,b)+limit],操作次数减1;
    • cost=0 的点 sum=a+b,操作次数再减1;
  3. 计算差分数组的前缀和,遍历所有可能的 x,找出最小操作次数。

3. 代码实现

java 复制代码
class Solution {
    public int minMoves(int[] nums, int limit) {
        int[] diff = new int[2 * limit + 2];
        int n = nums.length;

        for (int i = 0; i < n / 2; i++) {
            int a = nums[i];
            int b = nums[n - 1 - i];
            int sum = a + b;

            // 1. 初始:所有x需要2次修改
            diff[2] += 2;
            diff[2 * limit + 1] -= 2;

            // 2. 进入cost=1的区间,修改次数减1
            int l = Math.min(a, b) + 1;
            int r = Math.max(a, b) + limit;
            diff[l] -= 1;
            diff[r + 1] += 1;

            // 3. 进入cost=0的点,修改次数再减1
            diff[sum] -= 1;
            diff[sum + 1] += 1;
        }

        // 计算前缀和,找出最小修改次数
        int minOps = Integer.MAX_VALUE;
        int currentOps = 0;
        for (int x = 2; x <= 2 * limit; x++) {
            currentOps += diff[x];
            minOps = Math.min(minOps, currentOps);
        }
        return minOps;
    }
}

4. 代码优化说明

  • 差分数组仅需一次遍历即可完成区间更新,避免了暴力枚举所有 xO(n*limit) 复杂度;
  • 区间更新逻辑清晰,将三种修改次数的场景转化为差分数组的加减操作;
  • 前缀和计算仅需一次遍历,整体复杂度为线性级。

5. 复杂度分析

  • 时间复杂度 :O(n+limit)O(n + limit)O(n+limit)

    • 遍历互补对:O(n/2)O(n/2)O(n/2);
    • 差分数组前缀和遍历:O(2∗limit)O(2*limit)O(2∗limit);
    • 总时间复杂度为线性级。
  • 空间复杂度 :O(limit)O(limit)O(limit)

    • 差分数组大小为 2*limit+2,与 limit 成正比。

6. 总结

  • 核心思路是差分数组 + 前缀和,将多对元素的修改次数统计转化为区间更新问题;
  • 关键技巧:对每一对互补元素,按目标和 x 划分三种修改次数区间,用差分数组高效统计;
  • 本题是差分数组在区间更新问题中的经典应用,通过一次遍历完成所有区间更新,再通过前缀和得到结果。

关键点回顾

  1. 互补数组的核心是所有互补对的和相等;
  2. 对每一对元素,修改次数分为 0/1/2 三种情况,对应不同的目标和区间;
  3. 差分数组可高效实现区间加减操作,是解决此类问题的核心工具。
相关推荐
To_OC1 天前
LC 1 两数之和:面试第一道必考题,暴力解法直接被面试官 pass
javascript·算法·leetcode
鱼鱼不愚与1 天前
《原来如此 | 第01期:为什么导航软件能预测红绿灯倒计时?》
算法
复杂网络1 天前
论最小 Agent 计算机的形态
算法
kisshyshy2 天前
🍦 雪糕、食堂、火车厢:三幅漫画吃透栈、队列与链表
javascript·算法
猿人谷2 天前
不只是 CPU 阈值:STAR 如何用 GAT + Transformer 做容器级自动扩缩容?
人工智能·算法
复杂网络2 天前
Stable Diffusion 视觉大模型微调技术深度调研
算法
复杂网络2 天前
基于 Stable Diffusion 架构的视觉大模型代表性工作与原理深度解析
算法
MrZhao4002 天前
Agent Loop 如何用 Hook 扩展:权限、日志与工具拦截
算法
MrZhao4002 天前
Agent 为什么需要 Skills:别把所有知识都塞进 system prompt
算法