劍指Offer 調整陣列順序使奇數字於偶數前面

2022-08-29 08:21:07 字數 1802 閱讀 6509

目錄輸入乙個整數陣列,實現乙個函式來調整該陣列中數字的順序,使得所有奇數字於陣列的前半部分,所有偶數字於陣列的後半部分。

若在不考慮時間複雜度的情況下,可以從頭掃瞄這個陣列,每碰到乙個偶數,取出該數字,並把該數字後面的所有數字往前移一位。移完之後在陣列的末尾有乙個空位,再把該偶數放入到這個空位。由於每碰到乙個偶數就要移動 \(o(n)\)個數字,故總的時間複雜度為 \(o(n^2)\)

該題要求把奇數放到陣列的前半部分,偶數放在陣列的後半部分,因此所有的奇數應該在偶數的前面。那麼,在掃瞄這個陣列時,若發現有偶數在奇數的前面,就交換它們的順序。採用雙指標的解法如下所示:

void reorderoddeven(int* pdata, unsigned int length)

int* pbegin = pdata; // pbegin指標指向陣列的第乙個數字

int* pend = pdata + length -1; // pend指標指向陣列的最後乙個數字

while (pbegin < pend)

// 向前移動pend,直到它指向奇數

// (*pend & 0x1) == 0 表示pend指向的是偶數

while (pbegin < pend && (*pend & 0x1) == 0)

// 若pbegin指標指向的是偶數,pend指標指向的是奇數。則交換這兩個數字

if (pbegin < pend)

}

}

編寫**時我們思考的不應該只是解決乙個問題的方法,而是解決一系列同型別問題的通用方法,因為優秀的**應具有良好的可擴充套件性。可以將解法 2中的整個函式解耦成兩部分,一部分是判斷數字應該在陣列前半部分還是後半部分;另一部分是拆分陣列的操作。解耦後的**如下所示:

void reorder(int* pdata, unsigned int length, bool (*func)(int))

int* pbegin = pdata; // pbegin指標指向陣列的第乙個數字

int* pend = pdata + length -1; // pend指標指向陣列的最後乙個數字

while (pbegin < pend)

// 向前移動pend,直到它指向奇數

while (pbegin < pend && func(*pend))

// 若pbegin指標指向偶數,pend指標指向奇數,則交換這兩個數字

if (pbegin < pend)

}

}// 判斷乙個數是否為偶數

bool iseven(int n)

void reorderoddeven(int* pdata, unsigned int length)

若把問題改成將陣列中的負數移到非負數的前面,或者把能被 3 整除的數移到不能被 3 整除的數的前面,都只需定義新的函式來確定分組的標準,而函式 reorder 不需要進行任何改動。將陣列中的負數移到非負數的前面的**如下所示:

// 判斷乙個數是否為非負數

bool isnonnegative(int n)

void reordernonnegandneg(int* pdata, unsigned int length)

個人主頁:

www.codeapes.cn

劍指offer 調整陣列順序

時間限制 1秒 空間限制 32768k 本題知識點 陣列 題目描述 輸入乙個整數陣列,實現乙個函式來調整該陣列中數字的順序,使得所有的奇數字於陣列的前半部分,所有的偶數字於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。首先想到的是利用兩個輔助陣列,乙個儲存奇數,乙個儲存偶數,這樣的...

劍指offer(調整陣列順序)

輸入乙個整數陣列,實現乙個函式來調整該陣列中數字的順序,使得所有的奇數字於陣列的前半部分,所有的偶數字於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。1 暴力解法 從前到位掃瞄陣列,如果出現前面是偶數後面是奇數的情況,則交換。其中使用氣泡排序的思想。從後面朝前比較,使用外迴圈控制趟...

劍指offer(十三) 調整陣列順序

題目描述 輸入乙個整數陣列,實現乙個函式來調整該陣列中數字的順序,使得所有的奇數字於陣列的前半部分,所有的偶數字於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。題解 思路簡單的解法就是,建兩個臨時陣列,乙個奇數陣列,乙個偶數陣列,最後再組合起來即可,時間複雜度為o n 一解 pub...