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. 差分数组可高效实现区间加减操作,是解决此类问题的核心工具。
相关推荐
liulilittle1 小时前
TCP UCP v1.0:BBR 的非破坏性约束层
网络·c++·网络协议·tcp/ip·算法·c·通信
每天回答3个问题1 小时前
LeetCodeHot100|回溯算法、46.全排列、78.子集、17.电话号码的字母组合
算法·深度优先·回溯
YL200404262 小时前
038翻转二叉树
数据结构·leetcode
叁散2 小时前
实验项目1 LTE通信原理与应用
笔记·其他
AOwhisky2 小时前
Docker 学习笔记:镜像分发、容器运行与资源限制
笔记·学习·docker
Liangwei Lin3 小时前
LeetCode 287. 寻找重复数
算法·leetcode·职场和发展
OCR_133716212753 小时前
护照OCR校验位技术解析:从算法逻辑到工程落地,筑牢证件核验安全线
人工智能·算法
Hello.Reader3 小时前
算法基础(十三)——随机算法为什么有时主动引入随机性
java·数据库·算法
老鱼说AI4 小时前
现代 LangChain 开发指南:从 LCEL 原理到企业级 RAG 与 Agent 实战
java·开发语言·人工智能·深度学习·神经网络·算法·机器学习