
2025-12-01:最小相邻交换至奇偶交替。用go语言,给定一个由互不相同的整数组成的数组 nums。允许的操作是把数组中相邻的两个元素互换位置。若一个排列中每一对相邻元素的奇偶性交替出现(即任意相邻的一对中有且只有一个是偶数),则称该排列为“奇偶交错”排列。求将 nums 通过最少次相邻交换变为任意一种奇偶交错排列所需的最小交换次数;若无法通过任何相邻交换得到这样的排列,则返回 -1。
1 <= nums.length <= 100000。
1 <= nums[i] <= 1000000000。
nums 中的所有元素都是 唯一 的。
输入: nums = [2,4,6,5,7]。
输出:3。
解释:
将 5 和 6 交换,数组变成 [2,4,5,6,7]
将 5 和 4 交换,数组变成 [2,5,4,6,7]
将 6 和 7 交换,数组变成 [2,5,4,7,6]。此时是一个有效排列。因此答案是 3。
题目来自力扣3587。
nums,记录所有奇数元素的原下标位置。这是因为在奇偶交替排列中,奇数的放置位置决定了整体模式。例如,对于数组 [2,4,6,5,7],奇数元素是 5 和 7,它们的下标分别是 3 和 4。(n+1)//2(向上取整),模式B需要的奇数个数为 n//2(向下取整),其中 n 是数组长度。如果实际奇数个数 m 与模式要求不匹配,则该模式不可行。例如,当 n=5 时,模式A需要3个奇数,模式B需要2个奇数。若实际奇数个数为2,则模式A不可行。i 个奇数(按顺序)的目标索引是 i*2 + 0。i 个奇数的目标索引是 i*2 + 1。j 与目标下标之差的绝对值 |target_j - j|,并累加所有奇数的绝对值差。这个累加值即为该模式下的最小交换次数。因为相邻交换中,移动一个元素到距离 d 的位置需要 d 次交换,且元素互不相同,使得移动相互独立。例如,将奇数 5(下标3)移动到目标下标2,需要 |2-3|=1 次交换。-1。在示例 [2,4,6,5,7] 中,模式B可行(奇数个数2等于 5//2=2),计算出的距离和为3,故结果为3。O(n),其中 n 是数组长度。过程包括一次数组遍历(收集奇数下标)和两次对奇数列表的遍历(计算两种模式的距离),均为线性操作。O(n),主要用于存储奇数下标的列表,最坏情况下(全为奇数)需要 n 个空间。.
import math
from typing import List
def minSwaps(nums: List[int]) -> int:
pos1 = [] # 车(奇数)的下标
for i, x in enumerate(nums):
if x % 2 != 0:
pos1.append(i)
n = len(nums)
m = len(pos1)
def calc(start: int) -> int:
if (n - start + 1) // 2 != m:
return math.inf
res = 0
for i, j in enumerate(pos1):
res += abs(i * 2 + start - j)
return res
ans = min(calc(0), calc(1))
if ans == math.inf:
return-1
return ans
def main():
nums = [2, 4, 6, 5, 7]
result = minSwaps(nums)
print(result)
if __name__ == "__main__":
main()
.
# -*-coding:utf-8-*-
import math
from typing import List
def minSwaps(nums: List[int]) -> int:
pos1 = [] # 车(奇数)的下标
for i, x in enumerate(nums):
if x % 2 != 0:
pos1.append(i)
n = len(nums)
m = len(pos1)
def calc(start: int) -> int:
if (n - start + 1) // 2 != m:
return math.inf
res = 0
for i, j in enumerate(pos1):
res += abs(i * 2 + start - j)
return res
ans = min(calc(0), calc(1))
if ans == math.inf:
return-1
return ans
def main():
nums = [2, 4, 6, 5, 7]
result = minSwaps(nums)
print(result)
if __name__ == "__main__":
main()
.
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <climits>
using namespace std;
int minSwaps(vector<int>& nums) {
vector<int> pos1; // 车(奇数)的下标
for (int i = 0; i < nums.size(); i++) {
if (nums[i] % 2 != 0) {
pos1.push_back(i);
}
}
int n = nums.size();
int m = pos1.size();
auto calc = [&](int start) -> int {
if ((n - start + 1) / 2 != m) {
return INT_MAX;
}
int res = 0;
for (int i = 0; i < pos1.size(); i++) {
res += abs(i * 2 + start - pos1[i]);
}
return res;
};
int ans = min(calc(0), calc(1));
if (ans == INT_MAX) {
return-1;
}
return ans;
}
int main() {
vector<int> nums = {2, 4, 6, 5, 7};
int result = minSwaps(nums);
cout << result << endl;
return0;
}

我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。