轉載本文章請標明作者和出處
本文出自《Darwin的程序空間》
本文題目和部分解題思路來源自《劍指offer》第二版
題目
輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有奇數位於數組的前半部分,所有偶數位於數組的後半部分
示例
輸入:nums = [1,2,3,4]
輸出:[1,3,2,4]
注:[3,1,2,4] 也是正確的答案之一。
解題分析
這道題的核心邏輯就是將數據進行分堆處理,這裏筆者首先考慮到的做法是,可以再定義一個數組,和原數組一樣的長度;並且定義兩個指針left和right分別指向新數組的開頭和結尾;
然後遍歷原數組,如果是奇數,就賦值給新數組的left位,然後left++,如果是偶是,就賦值給新數組的right位,然後right–,直到left >= right,新數組就是滿足我們要求的所有奇數位於數組的前半部分,所有偶數位於數組的後半部分的數組;
這麼做我們只遍歷了一遍數組,但是定義了一個和原數組一樣長度的新數組,空間複雜度和時間複雜度都是O(n);
左右指針法:
我們同樣可以定義兩個指針left、right指向原數組的左右兩端;
然後左右兩個指針同時向中間移動,直到左指針碰到了偶數,右指針碰到了奇數(注意左右指針不要移出了數組,導致空指針異常),此時如果左指針在右指針的左邊,左右指針的元素交換,一直到左指針到了右指針右邊,說明已經交換完畢;
這樣做時間複雜度是O(n)、空間複雜度是O(1);
代碼(JAVA、Python3實現)
ps:這裏筆者使用的jdk爲1.8版本、python使用的3.7版本
- java實現
class Solution {
public int[] exchange(int[] nums) {
if (Objects.isNull(nums) || nums.length < 2) {
return nums;
}
int left = 0;
int right = nums.length - 1;
while (true) {
while (left < nums.length && nums[left] % 2 != 0) {
left++;
}
while (right >=0 && nums[right] % 2 == 0) {
right--;
}
if (left < right) {
/* 交換位置 */
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
} else {
break;
}
}
return nums;
}
}
- python實現(剛學了兩天python,用python寫把練練手)
class Solution:
def exchange(self, nums: List[int]) -> List[int]:
if nums is None or len(nums) < 2:
return nums
left = 0
right = len(nums) - 1
while True:
while left < len(nums) and nums[left] % 2 != 0:
left += 1
while right >= 0 and nums[right] % 2 == 0:
right -= 1
if left < right:
nums[left], nums[right] = nums[right], nums[left]
else:
break
return nums