2026-07-14:两个值之间的最小绝对差值。用go语言,给定一个只由 0、1、2 组成的整数数组 nums。 我们要找所有满足条件的下标对(i, j)
🤖 AI总结
主题
用Go、Python、C++求解数组中1和2的最小下标绝对差值问题。
摘要
文章详细讲解了力扣3880题,通过一次遍历和常数空间,求解数组中1和2的最小下标绝对差值,并给出Go、Python、C++三种代码实现。
关键信息
- 1 给定只含0,1,2的数组,求所有1和2下标对的最小绝对差值。
- 2 单次遍历,O(n)时间,O(1)空间,利用last数组记录最近位置。
- 3 若不存在有效对返回-1。
2026-07-14:两个值之间的最小绝对差值。用go语言,给定一个只由 0、1、2 组成的整数数组 nums。
我们要找所有满足条件的下标对(i, j),其中当 nums[i] 等于 1,且 nums[j] 等于 2 时,这样的(i, j)被称为“有效下标对”。
在所有有效下标对之中,计算每一对的下标差:|i – j|。
要求返回这些有效下标对里“最小的下标差”。
如果数组中根本不存在任何有效下标对(即不存在某个 i 使得 nums[i]=1 同时存在某个 j 使得 nums[j]=2),则返回 -1。
1 <= nums.length <= 100。
0 <= nums[i] <= 2。
输入: nums = [1,0,0,2,0,1]。
输出: 2。
解释:
有效下标对有:
(0, 3),其绝对差为 abs(0 – 3) = 3。
(5, 3),其绝对差为 abs(5 – 3) = 2。
因此,结果是 2。
题目来自力扣3880。
一、分步详细执行过程 步骤1:初始化基础变量
1. 计算数组长度 n = 6;
2. 定义答案变量 ans = n = 6(用数组长度作为初始最大值,后续找到更小差值就覆盖);
3. 初始化last = [-6, -6]:last[0]存最近1的下标,last[1]存最近2的下标,初始值-6。
步骤2:逐个遍历数组每个元素(下标i从0到5) 第1轮:i=0,元素x=1
1. 判断 x>0,满足条件进入逻辑;
2. x = x-1 = 0;
3. 计算对立编号:x^1 = 0^1 = 1;
4. 取出 last[1] = -6,计算差值 i – last[1] = 0 – (-6) = 6;
5. 执行 min(ans=6, 6),ans 保持6不变;
6. 更新 last[0] = i = 0:现在 last = [0, -6],记录下标0是最近出现的1。
第2轮:i=1,元素x=0
x不大于0,直接跳过所有计算逻辑,last数组、ans均无变化。
第3轮:i=2,元素x=0
x不大于0,直接跳过所有计算逻辑,last数组、ans均无变化。
第4轮:i=3,元素x=2
1. 判断 x>0,满足条件进入逻辑;
2. x = x-1 = 1;
3. 计算对立编号:x^1 = 1^1 = 0;
4. 取出 last[0] = 0,计算差值 i – last[0] = 3 – 0 = 3;
5. 执行 min(ans=6, 3),ans 更新为3;
6. 更新 last[1] = i = 3:现在 last = [0, 3],记录下标3是最近出现的2。
第5轮:i=4,元素x=0
x不大于0,直接跳过所有计算逻辑,last数组、ans均无变化。
第6轮:i=5,元素x=1
1. 判断 x>0,满足条件进入逻辑;
2. x = x-1 = 0;
3. 计算对立编号:x^1 = 0^1 = 1;
4. 取出 last[1] = 3,计算差值 i – last[1] = 5 – 3 = 2;
5. 执行 min(ans=3, 2),ans 更新为2;
6. 更新 last[0] = i = 5:现在 last = [5, 3],更新最近出现1的下标为5。
步骤3:遍历结束后判断返回值
遍历完成后 ans=2,ans不等于初始值n=6,说明存在有效1、2配对,直接返回ans=2,和题目输出一致。
补充边界场景逻辑(不存在有效配对)
如果数组只有1没有2 / 只有2没有1:遍历全程不会同时出现1和2,ans会一直等于初始值n,此时函数返回-1。
二、时间复杂度分析
1. 数组仅进行单层一次遍历,数组长度为n,循环执行n次;
2. 循环内部所有操作:数值转换、异或、取值、求最小值、数组赋值,全部是常数级 O(1) 运算;
3. 整体时间复杂度:O(n),n为输入数组长度。
三、额外空间复杂度分析
1. 仅固定开辟了两个变量:n、ans;
2. 固定长度数组 last,长度恒等于2,和输入数组长度n无关,属于常数空间;
3. 没有动态数组、切片、哈希表等随n增大而扩容的存储;
4. 整体额外空间复杂度:O(1)(常数空间)。
Go完整代码如下:
package main
import (
"fmt"
)
func minAbsoluteDifference(nums []int)int {
n := len(nums)
ans := n
// last[x] 表示 x+1 上一次出现的位置
last := [2]int{-n, -n} // i - (-n) >= n,不会让 ans 变小
for i, x := range nums {
if x > 0 {
// 如果 x 是 1,那么找上一个 2 的位置
// 如果 x 是 2,那么找上一个 1 的位置
x--
ans = min(ans, i-last[x^1])
last[x] = i
}
}
if ans == n {
return-1
}
return ans
}func main() {
nums := []int{1, 0, 0, 2, 0, 1}
result := minAbsoluteDifference(nums)
fmt.Println(result)
}
![]()
Python完整代码如下:
# -*-coding:utf-8-*-
from typing import List
def min_absolute_difference(nums: List[int]) -> int:
n = len(nums)
ans = n
# last[x] 表示 x+1 上一次出现的位置
last = [-n, -n] # i - (-n) >= n,不会让 ans 变小
for i, x in enumerate(nums):
if x > 0:
# 如果 x 是 1,那么找上一个 2 的位置
# 如果 x 是 2,那么找上一个 1 的位置
x -= 1
ans = min(ans, i - last[x ^ 1])
last[x] = i
if ans == n:
return-1
return ans
def main():
nums = [1, 0, 0, 2, 0, 1]
result = min_absolute_difference(nums)
print(result)if __name__ == "__main__":
main()
![]()
C++完整代码如下:
using namespace std;
int minAbsoluteDifference(vector& nums) {
int n = nums.size();
int ans = n;
// last[x] 表示 x+1 上一次出现的位置
int last[2] = {-n, -n}; // i - (-n) >= n,不会让 ans 变小
for (int i = 0; i < n; i++) {
int x = nums[i];
if (x > 0) {
// 如果 x 是 1,那么找上一个 2 的位置
// 如果 x 是 2,那么找上一个 1 的位置
x--;
ans = min(ans, i - last[x ^ 1]);
last[x] = i;
}
}
if (ans == n) {
return-1;
}
return ans;
}int main() {
vector nums = {1, 0, 0, 2, 0, 1};
int result = minAbsoluteDifference(nums);
cout << result << endl;
return0;
}
![]()
我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。