LeetCode-劍指Offer-21-調整數組順序使奇數位於偶數前面


題意描述:

輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有奇數位於數組的前半部分,所有偶數位於數組的後半部分。

提示:

  • 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]

總結:

  • 其實這道題有點像 快速排序 的思路。

發佈了169 篇原創文章 · 獲贊 39 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章