目錄輸入乙個整數陣列,實現乙個函式來調整該陣列中數字的順序,使得所有奇數字於陣列的前半部分,所有偶數字於陣列的後半部分。
若在不考慮時間複雜度的情況下,可以從頭掃瞄這個陣列,每碰到乙個偶數,取出該數字,並把該數字後面的所有數字往前移一位。移完之後在陣列的末尾有乙個空位,再把該偶數放入到這個空位。由於每碰到乙個偶數就要移動 \(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...