题目
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
示例:
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。
提示:
- 1 <= nums.length <= 50000
- 1 <= nums[i] <= 10000
解题
解题1:
借助额外的数组空间,遍历原数组判断元素值的奇偶;如果为奇数则放置在数组的左半部分,为偶数则放置在数组的有半部分。
时间复杂度:O(N)
空间复杂度:O(N)
public int[] exchange(int[] nums) {
int len = nums.length;
int[] res = new int[nums.length];
int first = 0;
int last = len -1;
for (int i = 0; i < nums.length; i++) {
if (nums[i]%2 == 0) {
res[last--] = nums[i];
} else {
res[first++] = nums[i];
}
}
return res;
}
解题2:
不使用额外的空间,就单独使用该数组,边判断边交换。
定义首位指针,分别判断首位指针的元素值的奇偶性;有以下几种情况:
- 首奇尾偶,首前进1尾后退1;
- 首奇尾奇,首前进1尾不动;
- 首偶尾偶,首不动尾前进1;
- 首偶尾奇,首尾交换并首前进1尾后退1
时间复杂度:O(N)
空间复杂度:O(1)
public int[] exchange(int[] nums) {
int first = 0;
int last = nums.length-1;
while (first < last) {
if (nums[first]%2!=0 && nums[last]%2==0) {
first++;
last--;
} else if(nums[first]%2!=0 && nums[last]%2!=0) {
first++;
} else if(nums[first]%2==0 && nums[last]%2==0) {
last--;
} else if (nums[first]%2==0 && nums[last]%2!=0) {
swap(nums,first,last);
first++;
last--;
}
}
return nums;
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
解题3:
定义快慢指针;判断快指针元素奇偶性,如果为奇则与慢指针交换,如果为偶则继续寻找奇数;
时间复杂度:O(N)
空间复杂度:O(1)
public int[] exchange(int[] nums) {
int quick = 0;
int slow = 0;
while (quick < nums.length) {
if (nums[quick]%2 != 0) {
swap(nums, quick, slow);
slow++;
}
quick++;
}
return nums;
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}