劍指Offer面試題:13.調整陣列順序使奇數位於偶數前面
一、題目:調整陣列順序使奇數位於偶數前面
題目:輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有奇數位於陣列的前半部分,所有偶數位於陣列的後半部分。
例如有以下一個整數陣列:12345,經過調整後可以為:15342、13542、13524等等。
二、解題思路
2.1 基本解法
如果不考慮時間複雜度,最簡單的思路應該是從頭掃描這個陣列,每碰到一個偶數時,拿出這個數字,並把位於這個數字後面的所有數字往前挪動一位。挪完之後在陣列的末尾有一個空位,這時把該偶數放入這個空位。由於每碰到一個偶數就需要移動O(n)個數字,因此總的時間複雜度是O(n2)。
2.2 高效解法
這裡可以參考快速排序的思想,快速排序的基本思想是:通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序的目的。
因此,我們可以借鑑快速排序的思想,通過設定兩個指標來進行交換操作,從而減少移動次數,提高效率:
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; inttemp = -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刷題】陣列題13:21 調整陣列順序使奇數位於偶數前面
【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:調整陣列順序使奇數位於偶數前面
題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 題目要求了在調整順序之後需要保證奇數和奇數,偶數和偶數之間的相對位置不變,因此,必須開闢新的
劍指offer 第13題 調整陣列順序使奇數位於偶數前面
描述: 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 思路: 方法一:利用sorted的key引數自定義比較規則 方法二:遍歷 程式碼: 方法一:
python刷題日記:劍指offer-調整陣列順序使奇數位於偶數前面
輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 解題思路 傳統方法應該是給兩個一前一後指標,遇到前偶數與後奇數時,就交換。然而我發現一個更簡便的方法,就是給兩個列表,奇偶分開放,最後
【劍指Offer】11調整陣列順序使奇數位於偶數前面
題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 時間限制:1秒;空間限制:32768K;本題知識點: 陣列 解題思路 思路一 建立一個新的陣列,先判
劍指offer——(4)調整陣列順序使奇數位於偶數前面
在這裡提供兩種思路。。 public class Solution { /* 最愚蠢的辦法:建立一個等長陣列,先迴圈一遍算出陣列中奇數的個數(或者偶數 的個數),再次迴圈,從頭開始放奇數,從尾到頭放偶數,最後將完成的陣列返回 */ public v
劍指offer刷題之調整陣列順序使奇數位於偶數前面
題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 # -*- coding:utf-8 -*- from collections impo