
2026-06-24:使数组奇偶交替的最少操作。用go语言,给定整数数组 nums。若对所有相邻位置 i 和 i+1,它们的奇偶性不同(一个为奇数、另一个为偶数),则称该数组为“奇偶交替”。你可以对任意下标 i 做一次操作:把 nums[i] 加 1 或减 1。
现在要返回两个数:
注意:当数组长度为 1 时,它天然满足“奇偶交替”条件。
1 <= nums.length <= 100000。
-1000000000 <= nums[i] <= 1000000000。
输入: nums = [-2,-3,1,4]。
输出: [2,6]。
解释:
执行以下操作:
将 nums[2] 增加 1,得到 nums = [-2, -3, 2, 4]。
将 nums[3] 减少 1,得到 nums = [-2, -3, 2, 3]。
得到的数组是奇偶交替的,且 max(nums) - min(nums) = 3 - (-3) = 6 是所有使用恰好 2 次操作可获得的奇偶交替数组中的最小值。
题目来自力扣3854。
函数输入0/1两种模板,一次性算出两个结果: 返回值1:该模板需要的总最少操作次数op 返回值2:该模板在最少操作前提下,修改后数组能达到的最小极差minD 函数内部完整执行流程:
核心判断条件:(x - i) & 1 != target,等价校验「当前x奇偶是否匹配当前模板要求」:
推导:
x奇偶 ^ i奇偶 = target → (x&1) ^ (i&1) = target
(x-i)&1 = (x&1)^(i&1),因此条件不成立代表当前数字奇偶不达标,必须修改。
分两种分支处理每个元素:
直接用原x更新mn、mx,不增加操作次数。
计算当前模板修改后数组极差:mx - mn;
题目规定数组长度≥2时极差至少为1,因此最终取max(mx-mn,1)作为该模板的最小极差minD;
函数返回 (总操作次数op,最小极差minD)。
数组下标0: -2、下标1: -3、下标2: 1、下标3:4
i=0,x=-2:x偶,i偶,匹配模板0,不操作,mn=-2,mx=-2 i=1,x=-3:x奇,i奇,匹配模板0,不操作,mn=-3,mx=-2 i=2,x=1:x奇,i偶,不匹配,op+1;x不是gMin/gMax,任意±1(示例选+1→2),新x=2,mn=-3,mx=2 i=3,x=4:x偶,i奇,不匹配,op+1;x是gMax=4,只能-1→3,新x=3,mn=-3,mx=3 总op1=2,极差3-(-3)=6 → minD1=6
i=0,x=-2偶,i偶,不匹配,op+1;x=gMin=-3?不是,x=-2,±1变-1 i=1,x=-3奇,i奇,不匹配,op+1;±1变-2 i=2,x=1奇,i偶,匹配,无操作 i=3,x=4偶,i奇,匹配,无操作 总op2=2;修改后数值区间极差会大于6,minD2>6
对比规则优先级:
示例中op1=op2=2,minD1=6 < minD2,因此选用模板0结果,返回数组[2,6],和题目输出一致。
如果输入数组长度等于1,直接返回[0,0],不执行上述calc计算流程。
.
package main
import (
"fmt"
"math"
"slices"
)
func makeParityAlternating(nums []int) []int {
iflen(nums) == 1 {
return []int{0, 0}
}
gMin := slices.Min(nums)
gMax := slices.Max(nums)
calc := func(target int) (int, int) {
op, mn, mx := 0, math.MaxInt, math.MinInt
for i, x := range nums {
// 如果 target = 0,那么操作后,nums 每个数的奇偶性必须分别等于 0,1,0,1,... 即 target ^ i%2
if (x-i)&1 != target { // 等价于 x&1 != target ^ i%2
op++
if x == gMin {
x++
} elseif x == gMax {
x--
}
}
mn = min(mn, x)
mx = max(mx, x)
}
return op, max(mx-mn, 1) // 在 n >= 2 的情况下,极差至少是 1
}
op1, minD1 := calc(0)
op2, minD2 := calc(1)
if op1 < op2 || op1 == op2 && minD1 < minD2 {
return []int{op1, minD1}
}
return []int{op2, minD2}
}
func main() {
nums := []int{-2, -3, 1, 4}
result := makeParityAlternating(nums)
fmt.Println(result)
}

.
# -*-coding:utf-8-*-
from typing import List
def make_parity_alternating(nums: List[int]) -> List[int]:
iflen(nums) == 1:
return [0, 0]
g_min = min(nums)
g_max = max(nums)
def calc(target: int) -> tuple:
op = 0
mn = float('inf')
mx = float('-inf')
for i, x in enumerate(nums):
# 如果 target = 0,那么操作后,nums 每个数的奇偶性必须分别等于 0,1,0,1,...
# 即 target ^ (i % 2)
if (x - i) & 1 != target: # 等价于 x&1 != target ^ i%2
op += 1
if x == g_min:
x += 1
elif x == g_max:
x -= 1
mn = min(mn, x)
mx = max(mx, x)
# 在 n >= 2 的情况下,极差至少是 1
return op, max(mx - mn, 1)
op1, min_d1 = calc(0)
op2, min_d2 = calc(1)
if op1 < op2 or (op1 == op2 and min_d1 < min_d2):
return [op1, min_d1]
return [op2, min_d2]
if __name__ == "__main__":
nums = [-2, -3, 1, 4]
result = make_parity_alternating(nums)
print(result)
.
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
vector<int> makeParityAlternating(vector<int>& nums) {
if (nums.size() == 1) {
return {0, 0};
}
int gMin = *min_element(nums.begin(), nums.end());
int gMax = *max_element(nums.begin(), nums.end());
auto calc = [&](int target) -> pair<int, int> {
int op = 0;
int mn = INT_MAX;
int mx = INT_MIN;
for (int i = 0; i < nums.size(); i++) {
int x = nums[i];
// 如果 target = 0,那么操作后,nums 每个数的奇偶性必须分别等于 0,1,0,1,...
// 即 target ^ i%2
if (((x - i) & 1) != target) { // 等价于 x&1 != target ^ i%2
op++;
if (x == gMin) {
x++;
} elseif (x == gMax) {
x--;
}
}
mn = min(mn, x);
mx = max(mx, x);
}
// 在 n >= 2 的情况下,极差至少是 1
return {op, max(mx - mn, 1)};
};
auto [op1, minD1] = calc(0);
auto [op2, minD2] = calc(1);
if (op1 < op2 || (op1 == op2 && minD1 < minD2)) {
return {op1, minD1};
}
return {op2, minD2};
}
int main() {
vector<int> nums = {-2, -3, 1, 4};
vector<int> result = makeParityAlternating(nums);
cout << result[0] << " " << result[1] << endl;
return0;
}
