1. 程式人生 > >劍指Offer面試題:13.調整陣列順序使奇數位於偶數前面

劍指Offer面試題:13.調整陣列順序使奇數位於偶數前面

一、題目:調整陣列順序使奇數位於偶數前面

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

  例如有以下一個整數陣列:12345,經過調整後可以為:15342、13542、13524等等。

二、解題思路

2.1 基本解法

  如果不考慮時間複雜度,最簡單的思路應該是從頭掃描這個陣列,每碰到一個偶數時,拿出這個數字,並把位於這個數字後面的所有數字往前挪動一位。挪完之後在陣列的末尾有一個空位,這時把該偶數放入這個空位。由於每碰到一個偶數就需要移動O(n)個數字,因此總的時間複雜度是O(n2)

2.2 高效解法

  這裡可以參考快速排序的思想,快速排序的基本思想是:通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序的目的

quick sort

  因此,我們可以借鑑快速排序的思想,通過設定兩個指標來進行交換操作,從而減少移動次數,提高效率:

  Step1.第一個指標初始化時指向陣列的第一個數字,它只向後移動;

  Step2.第二個指標初始化時指向陣列的最後一個數字,它只向前移動。

  Step3.在兩個指標相遇之前,第一個指標總是位於第二個指標的前面。如果第一個指標指向的數字是偶數,並且第二個指標指向的數字是奇數,我們就交換這兩個數字。

  下圖展示了調整陣列{1,2,3,4,5}使得奇數位於偶數前面的過程:

三、解決問題

3.1 程式碼實現

  (1)基本功能實現

    public static void ReorderOddEven(int[] datas)
    {
        if (datas == null || datas.Length <= 0)
        {
            return;
        }

        int begin = 0;
        int end = datas.Length - 1;
        int
temp = -1; while (begin < end) { // 向後移動begin,直到它指向偶數 while (begin < end && datas[begin] % 2 != 0) { begin++; } // 向前移動pEnd,直到它指向奇數 while (begin < end && datas[end] % 2 == 0) { end--; } if (begin < end) { // 交換偶數和奇數 temp = datas[begin]; datas[begin] = datas[end]; datas[end] = temp; } } }

  怎麼樣,看起來是不是和快速排序的程式碼如出一轍?

  (2)可擴充套件性實現

  如果把題目改成把陣列中的數按照大小分為兩部分,所有負數都在非負數的前面,又或者改改,變成把陣列中的數分為兩部分,能被3整除的數都在不能被3整除的數的前面。面對需求的變化,我們發現程式碼變化的部分很小,因此從可擴充套件性的角度考慮,我們可以改寫上面的程式碼如下,這裡利用了.NET中的“函式指標”—委託來實現。

  ①方法實現

    public static void ReorderOddEven(int[] datas, Predicate<int> func)
    {
        if (datas == null || datas.Length <= 0)
        {
            return;
        }

        int begin = 0;
        int end = datas.Length - 1;
        int temp = -1;

        while (begin < end)
        {
            // 向後移動begin,直到它指向偶數
            while (begin < end && !func(datas[begin]))
            {
                begin++;
            }
            // 向前移動pEnd,直到它指向奇數
            while (begin < end && func(datas[end]))
            {
                end--;
            }

            if (begin < end)
            {
                // 交換偶數和奇數
                temp = datas[begin];
                datas[begin] = datas[end];
                datas[end] = temp;
            }
        }
    }

  這裡使用了.NET中的預定義委託Predicate,有不瞭解預定義委託的朋友可以閱讀我另一篇博文:《.NET中那些所謂的新語法之三》,這裡就不再贅述了。

  ②如何呼叫

    // 判斷奇數還是偶數
    ReorderHelper.ReorderOddEven(numbers, new Predicate<int>((num) => num % 2 == 0));
    // 判斷是能否被3整除
    ReorderHelper.ReorderOddEven(numbers, new Predicate<int>((num) => num % 3 == 0));

  這裡使用了.NET中的Lambda表示式,同樣,有不瞭解Lambda表示式的朋友也可以閱讀我的另一篇博文:《.NET中那些所謂的新語法之三》,這裡也就不再贅述了。

3.2 單元測試

  首先,這裡封裝了一個用於比較兩個陣列中的元素值是否相等的輔助方法:

    // 輔助方法:對比兩個陣列是否一致
    public bool ArrayEqual(int[] ordered, int[] expected)
    {
        if (ordered.Length != expected.Length)
        {
            return false;
        }

        bool result = true;
        for (int i = 0; i < ordered.Length; i++)
        {
            if (ordered[i] != expected[i])
            {
                result = false;
                break;
            }
        }

        return result;
    }
View Code

  (1)功能測試

    // Test1:輸入陣列中的奇數、偶數交替出現
    [TestMethod]
    public void ReorderTest1()
    {
        int[] numbers = { 1, 2, 3, 4, 5, 6, 7 };
        int[] expected = { 1, 7, 3, 5, 4, 6, 2 };
        ReorderHelper.ReorderOddEven(numbers);
        Assert.AreEqual(ArrayEqual(numbers, expected), true);
    }

    // Test2:輸入陣列中的所有偶數都出現在奇數的前面
    [TestMethod]
    public void ReorderTest2()
    {
        int[] numbers = { 2, 4, 6, 1, 3, 5, 7 };
        int[] expected = { 7, 5, 3, 1, 6, 4, 2 };
        ReorderHelper.ReorderOddEven(numbers);
        Assert.AreEqual(ArrayEqual(numbers, expected), true);
    }

    // Test3:輸入陣列中的所有奇數都出現在偶數的前面
    [TestMethod]
    public void ReorderTest3()
    {
        int[] numbers = { 1, 3, 5, 7, 2, 4, 6 };
        int[] expected = { 1, 3, 5, 7, 2, 4, 6 };
        ReorderHelper.ReorderOddEven(numbers);
        Assert.AreEqual(ArrayEqual(numbers, expected), true);
    }

  (2)特殊輸入測試

    // Test4:輸入的陣列只包含一個數字-奇數
    [TestMethod]
    public void ReorderTest4()
    {
        int[] numbers = { 1 };
        int[] expected = { 1 };
        ReorderHelper.ReorderOddEven(numbers);
        Assert.AreEqual(ArrayEqual(numbers, expected), true);
    }

    // Test5:輸入的陣列只包含一個數字-偶數
    [TestMethod]
    public void ReorderTest5()
    {
        int[] numbers = { 2 };
        int[] expected = { 2 };
        ReorderHelper.ReorderOddEven(numbers);
        Assert.AreEqual(ArrayEqual(numbers, expected), true);
    }

    // Test6:NULL指標
    [TestMethod]
    public void ReorderTest6()
    {
        int[] numbers = null;
        int[] expected = null;
        ReorderHelper.ReorderOddEven(numbers);
        Assert.AreEqual(numbers, expected);
    }

  (3)測試結果

  ①用例通過情況

  ②程式碼覆蓋率

作者:周旭龍

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。

相關推薦

Offer試題13.調整陣列順序使奇數位於偶數前面

一、題目:調整陣列順序使奇數位於偶數前面 題目:輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有奇數位於陣列的前半部分,所有偶數位於陣列的後半部分。   例如有以下一個整數陣列:12345,經過調整後可以為:15342、13542、13524等等。 二、解題思路 2.1 基本解

Offer》題目調整數組順序使奇數位於偶數前面

code ont else 指向 偶數 span cnblogs for emp 題目描述:調整數組順序使奇數位於偶數前 輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有的奇數位於數組的前半部分,所有的偶數位於位於數組的後半部分,並保證奇數和奇數,偶數和偶數

【LeetCode & offer刷題】陣列1321 調整陣列順序使奇數位於偶數前面

【LeetCode & 劍指offer 刷題筆記】目錄(持續更新中...) 21 調整陣列順序使奇數位於偶數前面 題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分, 所有的偶數位於陣列的後

offer(13) 調整陣列順序使奇數位於偶數前面

題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 解題思路 程式碼的完整性 這個題呢,需要調整奇偶數的順序,而且原先的相對位置不變。 頭指標從左向右遍歷,直至遇到

13.調整陣列順序使奇數位於偶數前面-offer-Python2.7

題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 思路 新建兩個空白陣

offer66題--Java實現,c++實現和python實現 13.調整陣列順序使奇數位於偶數前面

題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 C++實現 class Solution { public: void reOrderArray(v

13 調整陣列順序使奇數位於偶數前面

需要記錄排好序的最後一個奇數的位置odd_end 然後遇到奇數就一個一個向前交換,將該奇數交換到odd_end+1位置,更新odd_end=odd_end+1 class Solution { public: void reOrderArray(vector<int>

13.調整陣列順序使奇數位於偶數前面

題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 題目解答 public class Solution { public vo

3.13 調整陣列順序使奇數位於偶數前面

輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 方法一: void reOrderArray(vector<int> &array) { v

Offer學習】【試題14 調整陣列順序使奇數位於偶數前面

題目:輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有奇數位於陣列的前半部分,所有偶數位予陣列的後半部分。 這個題目要求把奇數放在陣列的前半部分, 偶數放在陣列的後半部分,因此所有的奇數應該位於偶數的前面。也就是說我們在掃描這個陣列的時候, 如

offer試題21調整陣列順序使奇數位於偶數前面

題目1:輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有奇數位於陣列的前半部分,所有偶數位於陣列的後半部分。 如果不考慮時間複雜度,最簡單的思路應該是從頭掃描這個陣列,每碰到一個偶數時,拿出這個數字,並把位於這個數字後面的所有的數字往前面挪動一位。挪完之後在陣列的末

Offer - 13調整陣列順序使奇數位於偶數前面

題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變 題目連結:https://www.nowcoder.com/practice/beb5aa2

offer-13調整陣列順序使奇數位於偶數前面

題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 思路 參考插入排序法 1.要想保證原有次序,則只能順次移動或相鄰交換。 2.i從左向右遍歷,找到第一

Offer:試題14——調整陣列順序使奇數位於偶數前面(java實現)

問題描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有奇數位於陣列的前半部分,所有偶數位於陣列的後半部分。 思路: 1.最簡單的想法,不考慮時間複雜度,掃描陣列,

offer調整陣列順序使奇數位於偶數前面

題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 題目要求了在調整順序之後需要保證奇數和奇數,偶數和偶數之間的相對位置不變,因此,必須開闢新的

offer13調整陣列順序使奇數位於偶數前面

描述: 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 思路: 方法一:利用sorted的key引數自定義比較規則 方法二:遍歷 程式碼: 方法一:

python刷題日記offer-調整陣列順序使奇數位於偶數前面

輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 解題思路 傳統方法應該是給兩個一前一後指標,遇到前偶數與後奇數時,就交換。然而我發現一個更簡便的方法,就是給兩個列表,奇偶分開放,最後

Offer】11調整陣列順序使奇數位於偶數前面

題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 時間限制:1秒;空間限制:32768K;本題知識點: 陣列 解題思路 思路一 建立一個新的陣列,先判

offer——(4)調整陣列順序使奇數位於偶數前面

在這裡提供兩種思路。。  public class Solution { /* 最愚蠢的辦法:建立一個等長陣列,先迴圈一遍算出陣列中奇數的個數(或者偶數 的個數),再次迴圈,從頭開始放奇數,從尾到頭放偶數,最後將完成的陣列返回 */ public v

offer刷題之調整陣列順序使奇數位於偶數前面

題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 # -*- coding:utf-8 -*- from collections impo