可以原地重构数组实现偶数在前奇数在后;用左右双指针,i从头找奇数、j从尾找偶数,找到即交换,直至i≥j,时间O(n)、空间O(1)。

用双指针可以在原地完成“偶数在前、奇数在后”的数组重构,时间复杂度 O(n),空间复杂度 O(1),不需要额外数组。
核心思路:左右双指针向中间靠拢
左指针从头开始找奇数,右指针从尾开始找偶数;一旦找到,就交换。重复直到两指针相遇。
- 左指针 i 初始为 0,只往右走,停在第一个奇数位置
- 右指针 j 初始为 length - 1,只往左走,停在第一个偶数位置
- 当 i 且两者都停住时,交换 nums[i] 和 nums[j]
- 交换后各自移动一步(i++,j--),继续下一轮查找
关键细节:判断奇偶要高效准确
用 nums[i] & 1 == 0 判断偶数更简洁安全(比 % 2 == 0 少一次取模运算,且对负数也适用)。
- nums[i] & 1 == 0 → 偶数(位与操作,推荐)
- nums[i] & 1 == 1 → 奇数
- 避免用
nums[i] % 2 == 0,因为负奇数(如 -3)取模结果是 -1,会误判
完整可运行代码示例
// 输入: [1, 2, 3, 4, 5, 6]
// 输出: [6, 2, 4, 3, 5, 1](偶数在前,顺序不保证稳定)
立即学习“Java免费学习笔记(深入)”;
public static void reorderEvenOdd(int[] nums) {
if (nums == null || nums.length <= 1) return;
int i = 0, j = nums.length - 1;
while (i < j) {
while (i < j && (nums[i] & 1) == 0) i++; // 找奇数
while (i < j && (nums[j] & 1) == 1) j--; // 找偶数
if (i < j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
i++;
j--;
}
}
}注意事项:这不是稳定排序
该算法只保证偶数全在奇数前面,不保持偶数之间或奇数之间的原始相对顺序。
- 如 [3, 1, 2, 4] 可能变成 [4, 2, 1, 3] 或 [2, 4, 3, 1],取决于扫描过程
- 若需稳定(即保持同类数字原有顺序),就得用额外空间,比如两个列表分别收集再合并
- 本解法优势在于原地、高效、简洁,适合面试和一般业务场景


















