题意描述:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
提示:
- 1 <= nums.length <= 50000
- 1 <= nums[i] <= 10000
示例:
一:
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一
解题思路:
Alice: 有点像快速排序里面的思想呀,用两个双指针,一个从前往后找偶数,一个从后往前找奇数,找到了就交换,一次让两个数字回归正常的位置,然后重复,直到两个指针相遇。
Bob: 对对对,这样应该是最快的写法了吧。
Alice: 面试的时候还要再确认一下是不是可以修改参数数组,如果不是的话,那就可在复制数组的时候直接分来了,也用双指针。
Bob: o( ̄▽ ̄)d
代码:
Python 方法一: 双指针
class Solution:
def exchange(self, nums: List[int]) -> List[int]:
left = 0
right = len(nums)-1
while left < right:
while left < right:
if nums[left] % 2 == 0:
break
left += 1
while left < right:
if nums[right] % 2 == 1:
break
right -= 1
nums[left], nums[right] = nums[right], nums[left]
left += 1
right -= 1
return nums
Python 方法二: 使用两个数组存放奇数和偶数,最后合并。
class Solution:
def exchange(self, nums: List[int]) -> List[int]:
tmp_odd = []
tmp_even = []
for x in range(len(nums)):
if nums[x] % 2 == 0:
tmp_even.append(nums[x])
else:
tmp_odd.append(nums[x])
return tmp_odd + tmp_even
Java 方法一:双指针
class Solution {
public int[] exchange(int[] nums) {
int left = 0;
int right = nums.length - 1;
while(left < right){
// 在左侧找到一个偶数
while(left < right){
if(nums[left] % 2 == 0){
break;
}
left ++;
}
// 在右侧找到一个奇数
while(left < right){
if(nums[right] % 2 == 1){
break;
}
right --;
}
// 交换这两个数
int tmp = nums[left];
nums[left] = nums[right];
nums[right] = tmp;
left ++;
right --;
}
return nums;
}
}
Java 方法二:使用数组 + 双指针。
class Solution {
public int[] exchange(int[] nums) {
int[] ret = new int[nums.length]; // 用来存储最后的结果
int left = 0;
int right = nums.length-1; // 双指针
for(int i=0; i<nums.length; ++i){ // O(n)时间复杂度
if(nums[i] % 2 == 0){
ret[right--] = nums[i];
}else{
ret[left++] = nums[i];
}
}
return ret;
}
}
易错点:
- 一些测试用例:
[1]
[2]
[2,1]
[1,1,3,5]
[1,1,2,3,5]
- 答案:
[1]
[2]
[1,2]
[1,1,3,5]
[1,1,5,3,2]
总结:
- 其实这道题有点像 快速排序 的思路。