news 2026/4/26 8:16:45

2026-04-26:使循环数组余额非负的最少移动次数。用go语言,给定一个环形排列的数组 balance,长度为 n,其中 balance[i] 表示第 i 个人当前的净余额(正数代表有剩余,负数代

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
2026-04-26:使循环数组余额非负的最少移动次数。用go语言,给定一个环形排列的数组 balance,长度为 n,其中 balance[i] 表示第 i 个人当前的净余额(正数代表有剩余,负数代

2026-04-26:使循环数组余额非负的最少移动次数。用go语言,给定一个环形排列的数组 balance,长度为 n,其中 balance[i] 表示第 i 个人当前的净余额(正数代表有剩余,负数代表欠债)。

在一次操作中,你可以选择某个人,把恰好 1 单位余额转给他的左邻居或右邻居(因为是环形,首尾相邻)。

目标:通过若干次这样的转移,使得所有位置的余额都变为非负(即每个人都不再欠债)。

要求:输出实现该目标的最小操作次数;如果从初始状态出发无法做到,则输出 -1。

已知条件:初始时数组中最多只有一个位置的余额为负。

1 <= n == balance.length <= 100000。

-1000000000 <= balance[i] <= 1000000000。

balance 中初始至多有一个负值。

输入:balance = [1,2,-5,2]。

输出:6。

解释:

一种最优的移动序列如下:

从 i = 1 移动 1 个单位到 i = 2,结果 balance = [1, 1, -4, 2]

从 i = 1 移动 1 个单位到 i = 2,结果 balance = [1, 0, -3, 2]

从 i = 3 移动 1 个单位到 i = 2,结果 balance = [1, 0, -2, 1]

从 i = 3 移动 1 个单位到 i = 2,结果 balance = [1, 0, -1, 0]

从 i = 0 移动 1 个单位到 i = 1,结果 balance = [0, 1, -1, 0]

从 i = 1 移动 1 个单位到 i = 2,结果 balance = [0, 0, 0, 0]

因此,所需的最小移动次数是 6。

题目来自力扣3776。

代码执行过程详细拆解


第一步:遍历数组,统计核心信息

  1. 计算数组所有元素的总和:1+2+(-5)+2 = 0
  2. 遍历过程中记录唯一的负数位置:只有索引2的值是-5,因此negIdx=2
  3. 基础校验:
    • 总和=0 ≥ 0,满足可以完成的条件;
    • 存在负数,需要计算移动次数。

第二步:确定核心需求

负数位置是索引2,余额为-5,需要补充5单位余额才能变成0(非负),记need=5(需要的总余额数)。
初始化总操作次数ans=0


第三步:按距离分层收集余额(环形就近原则,最小步数)

因为是环形数组,我们从离负数位置最近的地方开始收集余额(距离越近,移动步数越少,符合最小操作次数要求),距离从1开始依次递增:

距离 dis=1(离索引2最近的左右邻居)

  1. 找环形数组中,距离negIdx=2为1的两个位置:
    • 左邻居:(2-1+4)%4 = 1
    • 右邻居:(2+1)%4 = 3
  2. 这两个位置的余额:索引1=2,索引3=2,总和s=2+2=4
  3. 计算:
    • 当前需要5单位,这两个位置能提供4单位,全部用完
    • 操作次数 += 4 × 1(4个单位,每个移动1步)→ ans=4
    • 剩余需要的余额:need=5-4=1

距离 dis=2(下一层更远的位置)

  1. 找环形数组中,距离negIdx=2为2的两个位置:
    • 左邻居:(2-2+4)%4 = 0
    • 右邻居:(2+2)%4 = 0(环形数组,距离2时左右是同一个位置)
  2. 这个位置的余额:索引0=1,总和s=1
  3. 计算:
    • 剩余只需要1单位,这个位置恰好能提供1单位
    • 操作次数 += 1 × 2(1个单位,每个移动2步)→ ans=4+2=6
    • need=0,需求满足,结束计算

第四步:返回结果

总操作次数为6,与题目示例输出一致。


时间复杂度与额外空间复杂度分析

1. 时间复杂度

  • 第一步遍历数组:执行了n次操作(n是数组长度);
  • 第三步按距离收集余额:因为最多只有1个负数,且我们是就近收集,循环次数远小于n,可以视为常数次;
  • 整体总操作次数与数组长度n成正比 →时间复杂度为 O(n)

2. 额外空间复杂度

  • 代码中只定义了total、negIdx、need、ans、dis、s常数个变量
  • 没有创建任何与数组长度n相关的额外数组、集合等数据结构;
  • 额外空间复杂度为 O(1)(常数级空间)。

总结

  1. 执行核心流程:统计总和→定位唯一负数→校验合法性→就近分层收集余额→累加步数→返回结果;
  2. 时间复杂度:O(n)(线性复杂度,适合题目n≤100000的大数据量);
  3. 额外空间复杂度:O(1)(仅使用固定变量,无额外内存开销)。

Go完整代码如下:

packagemainimport("fmt")funcminMoves(balance[]int)int64{total:=0negIdx:=-1fori,x:=rangebalance{total+=xifx<0{negIdx=i}}iftotal<0{// 总和必须非负return-1}ifnegIdx<0{// 没有负数,无需操作return0}n:=len(balance)need:=-balance[negIdx]ans:=0fordis:=1;;dis++{// 把与 negIdx 相距 dis 的数移到 negIdxs:=balance[(negIdx-dis+n)%n]+balance[(negIdx+dis)%n]ifs>=need{ans+=need*dis// need 个 1 移动 dis 次returnint64(ans)}ans+=s*dis// s 个 1 移动 dis 次need-=s}}funcmain(){balance:=[]int{1,2,-5,2}result:=minMoves(balance)fmt.Println(result)}

Python完整代码如下:

# -*-coding:utf-8-*-fromtypingimportListdefminMoves(balance:List[int])->int:total=0neg_idx=-1fori,xinenumerate(balance):total+=xifx<0:neg_idx=iiftotal<0:# 总和必须非负return-1ifneg_idx<0:# 没有负数,无需操作return0n=len(balance)need=-balance[neg_idx]ans=0dis=1whileTrue:# 把与 neg_idx 相距 dis 的数移到 neg_idxleft=balance[(neg_idx-dis)%n]right=balance[(neg_idx+dis)%n]s=left+rightifs>=need:ans+=need*dis# need 个 1 移动 dis 次returnans ans+=s*dis# s 个 1 移动 dis 次need-=s dis+=1if__name__=="__main__":balance=[1,2,-5,2]result=minMoves(balance)print(result)

C++完整代码如下:

#include<iostream>#include<vector>#include<cmath>usingnamespacestd;longlongminMoves(vector<int>&balance){inttotal=0;intnegIdx=-1;for(inti=0;i<balance.size();i++){total+=balance[i];if(balance[i]<0){negIdx=i;}}if(total<0){// 总和必须非负return-1;}if(negIdx<0){// 没有负数,无需操作return0;}intn=balance.size();intneed=-balance[negIdx];longlongans=0;for(intdis=1;;dis++){// 把与 negIdx 相距 dis 的数移到 negIdxintleft=balance[(negIdx-dis+n)%n];intright=balance[(negIdx+dis)%n];ints=left+right;if(s>=need){ans+=static_cast<longlong>(need)*dis;// need 个 1 移动 dis 次returnans;}ans+=static_cast<longlong>(s)*dis;// s 个 1 移动 dis 次need-=s;}}intmain(){vector<int>balance={1,2,-5,2};longlongresult=minMoves(balance);cout<<result<<endl;return0;}

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/26 8:15:14

音乐自由之路:解锁网易云音乐加密文件的实用指南

音乐自由之路&#xff1a;解锁网易云音乐加密文件的实用指南 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾经遇到过这样的情况&#xff1a;在网易云音乐下载了心爱的歌曲&#xff0c;却只能在特定应用内播放&#xff0c;无…

作者头像 李华
网站建设 2026/4/26 8:08:09

python数据类型_字符串常用操作(详解)

这次主要介绍字符串常用操作方法及例子1.python字符串在python中声明一个字符串&#xff0c;通常有三种方法&#xff1a;在它的两边加上单引号、双引号或者三引号&#xff0c;如下&#xff1a;123name helloname1 "hello bei jing "name2 hello shang hai hahapyt…

作者头像 李华
网站建设 2026/4/26 8:07:04

AI推理性能翻倍实战手册(CUDA 13.2 + cuBLASLt 1.2.4 最优配置白皮书)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;AI推理性能瓶颈与CUDA 13架构演进全景图 现代大模型推理面临显存带宽饱和、kernel launch开销高、低精度计算单元利用率不足等多重瓶颈。CUDA 13&#xff08;2023年发布&#xff09;并非简单迭代&#…

作者头像 李华
网站建设 2026/4/26 8:06:01

3步快速配置罗技鼠标宏,轻松实现绝地求生无后坐力压枪

3步快速配置罗技鼠标宏&#xff0c;轻松实现绝地求生无后坐力压枪 【免费下载链接】logitech-pubg PUBG no recoil script for Logitech gaming mouse / 绝地求生 罗技 鼠标宏 项目地址: https://gitcode.com/gh_mirrors/lo/logitech-pubg 绝地求生罗技鼠标宏项目是一个…

作者头像 李华
网站建设 2026/4/26 8:05:04

感知机算法原理与Python实现详解

1. 感知机算法基础解析感知机是神经网络中最基础的组成单元&#xff0c;模拟了生物神经元的工作机制。想象一下&#xff0c;当你的手指碰到热水时&#xff0c;皮肤中的神经细胞会立即将信号传递给大脑——感知机就像这个过程的简化数学模型。它接收多个输入信号&#xff0c;经过…

作者头像 李华
网站建设 2026/4/26 8:04:50

NHSE完整指南:动物森友会存档编辑器从入门到精通

NHSE完整指南&#xff1a;动物森友会存档编辑器从入门到精通 【免费下载链接】NHSE Animal Crossing: New Horizons save editor 项目地址: https://gitcode.com/gh_mirrors/nh/NHSE 还在为《集合啦&#xff01;动物森友会》中收集稀有物品而烦恼吗&#xff1f;想快速打…

作者头像 李华