# 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
大家好,我是吴师兄。
今天继续来学习《剑指Offer》系列的一道经典题目,依旧给出了非常详细的题解和精美的配图与动画。
# 一、题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
示例:
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。
提示:
0 <= nums.length <= 50000
0 <= nums[i] <= 10000
# 二、题目解析
这道题目最终可以得到一个这样的数组,左边的部分都是奇数,右边的部分都是偶数。
如上图所示,绿色部分都是奇数,黄色部分都是偶数,并且此时 left 指向了奇数的最后一个元素,right 指向了偶数的第一个元素。
为了得到这样一个结果,需要执行如下的操作:
- 1、设置两个指针 left 和 right,left 指向当前区间的最左侧元素,right 指向当前区间的最右侧元素。
- 2、left 向右移动,right 向左移动,并且要使得 left 左边的元素(包含 left 本身)都是奇数,right 右边的元素(包含 right 本身)都是偶数。
- 3、如果 left 指针指向的元素值是奇数,那么说明该元素在左侧了,观察其它的元素,即让 left 向右移动。
- 4、如果 right 指针指向的元素值是偶数,那么说明该元素在右侧了,观察其它的元素,即让 right 向左移动。
- 5、否则就说明,此时要么 left 指向的元素值为偶数,要么 right 指向的元素值为奇数,它们不在正确的位置上,需要交换一下。
为了帮助你更好的理解整个过程,我特意做了一组动画,点开可以查看:
# 三、参考代码
// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
class Solution {
public int[] exchange(int[] nums) {
// 定义头指针 left
int left = 0 ;
// 定义尾指针 right
int right = nums.length - 1;
// 定义临时变量 tmp
int tmp;
// 移动 left 和 right ,直到 left 在 right 右侧或者相遇为止
while(left < right) {
// 如果 left 指针指向的元素值是奇数,那么说明该元素在左侧了,观察其它的元素,即让 left 向右移动
while(left < right && (nums[left] & 1) == 1) left++;
// 如果 right 指针指向的元素值是偶数,那么说明该元素在右侧了,观察其它的元素,即让 right 向左移动
while(left < right && (nums[right] & 1) == 0) right--;
// 否则就说明,此时要么 left 指向的元素值为偶数,要么 right 指向的元素值为奇数
// 交换这两个位置的元素
tmp = nums[left];
nums[left] = nums[right];
nums[right] = tmp;
}
// 最后返回结果就行
return nums;
}
}