1. 程式人生 > >LeetCode 按奇偶排序陣列(雙向寫+位運算)

LeetCode 按奇偶排序陣列(雙向寫+位運算)

今天開啟LeetCode做到這題的時候,發現已經忘記怎麼用指標了。
在這裡插入圖片描述

首先講講這題的思路吧,要實現很簡單,遍歷一遍取所有的偶數,再遍歷一遍取所有的奇數加到新數組裡去。但其實可以優化成遍歷一遍的:因為陣列是定長的,偶數個數+奇數個數 = 總個數。所以我只要遍歷一遍,如果是偶數就從前往後寫,如果是奇數就從後往前寫:

int odd = ASize - 1;//奇數從末尾往前寫
int even = 0;//偶數從前開始往後寫

完整程式碼

int* sortArrayByParity(int* A, int ASize, int* returnSize) {
    *returnSize  = ASize;
    int* ResArray = (int*) malloc((*returnSize)*sizeof(int));
    
    int even = 0;
    int odd = *returnSize - 1;
    
    for(int i = 0;i < ASize;i++){
        if(A[i]&1){
            ResArray[odd--] = A[i];
        }
        else{
            ResArray[even++] = A[i];
        }
    }
    
    return ResArray;
}

在這裡插入圖片描述

不知道讀者有沒有發現,我是用A[i]&1來判斷奇偶的,值為1的是奇數,值為0的是偶數。

&是位運算中的按位與運算子號,比如說5的二進位制是101,1的二進位制是1,補成和5一樣的三位,是001。現在我們把101和001進行按位與運算,得到結果是001,即1。

顯然奇數最低位必為1,而偶數最後一位必為0,和1進行與運算只有0、1兩個結果,因為1的高位補0,與運算結果永遠是0。

使用位運算比平時常見的A[i]%2==0方法來判斷奇偶快多了!如果我把那行if改成

if(A[i]%2==1)

提交結果是

在這裡插入圖片描述

然後發現這道題還有

思路很簡單,因為題目保證奇數偶數各一半,所以用odd和even記錄下一個空位的下標。odd:1、3、5、7……;even:0、2、4、6……

int* sortArrayByParityII(int* A, int ASize, int* returnSize) {
    *returnSize = ASize;
    int* ResArray = (int*) malloc(*returnSize*sizeof(int));
    int odd = 1;
    int even = 0;
    
    for(int i=0;i<ASize;i++){
        if(A[i]&1)
        {
            ResArray[odd] = A[i];
            odd+=2;
        }
        else{
            ResArray[even] = A[i];
            even+=2;
        }
    }
    return ResArray;
}

在這裡插入圖片描述