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


面試題:調整數組順序使奇數位於偶數前面

      當拿到這個題目,你首先會想到的是遍歷這個數組每碰到偶數時,拿出這個數字與其后的數字交換,但這樣的話其時間復雜度為O(n*n)

若面試官沒有時間復雜度的要求,那么這樣就可以了

但是往往不能體現出你的能力,你還可以優化

    1)我們可以維護兩個指針,第一個指針指向數組第一個數字第二個指針指向數組最后一個數字

    2)第一個指針只能在第二個指針前面,若相遇就停止移動(表明所有奇數均在偶數前面)

    3)第一個指針只往后移動直至遇上偶數

    4)第二個指針只往前移動至遇上奇數

     5)當兩個指針符合條件時就交換兩個指針所指向的數字

void ReorderOddEven(int *pData, unsigned int length)
{
if (pData == NULL || length == 0)
return;
int *start = pData;
int *end = pData + length - 1;
while (start < end)
{
while (start < end && (*start & 0x1) != 0)
{
start++;
}
while (start < end && (*end & 0x1) == 0)
{
end++;
}
if (start < end)
{
int tmp = *start;
*start = *end;
*end = tmp;
}
}
}

其實還可以再次優化,想想如果面試官再次改變條件,例如:想要所有非負數均在負數前面、所有可以整除5的數均在不能整除5的數的前面.....等等這些條件,首先你想到的是再寫一個函數來實現,那能不能有更好的方法來解決呢,答案是肯定的,可以只修改ReorderOddEven函數的兩處判斷條件 ,利用一個函數指針來單獨處理次數是否符合條件,此時代碼就能得到復用

void Reorder(int *pData, unsigned int length, bool(*func)(int))
{
if (pData == NULL || length == 0)
return;
int *start = pData;
int *end = pData + length - 1;
while (start < end)
{
while (start < end && !func(*end))
start++;
while (start < end && func(*end))
end--;
if (start < end)
{
int tmp = *start;
*start = *end;
*end = tmp;
}
}
}
bool isEven(int n)
{
return (n & 1) == 0;
}
void ReorderOddEven(int *pData, unsigned int length)
{
Reorder(pData, length, isEven);
}


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com