題意描述:
輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有奇數位於數組的前半部分,所有偶數位於數組的後半部分。
提示:
- 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]
總結:
- 其實這道題有點像 快速排序 的思路。