輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得全部的奇數位於數組的前半部分,全部的偶數位於數組的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。算法
最直接的思路是再構建一個新數組,先遍歷一遍原數組,把其中的奇數依次添加到新數組中,再遍歷一遍原數組把其中的偶數依次添加到新數組中,時間複雜度爲O(2n)。實現代碼以下數組
public int[] reOrderArray2(int[] array) { int[] arr = new int[array.Length]; int index = 0; for (int i = 0; i < array.Length; i++) { // 奇數 if ((array[i] % 2) != 0) { arr[index] = array[i]; index++; } } for (int i = 0; i < array.Length; i++) { // 偶數 if ((array[i] % 2) == 0) { arr[index] = array[i]; index++; } } return arr; }
C#的數組是不支持動態添加元素的,咱們可使用泛型List,來實如今指定位置插入元素。基本思路是遍歷原數組,依次將元素插入到List中,若是是偶數元素,默認插入到List的末尾。若是是奇數元素,則插入到全部的偶數元素以前(已插入的全部奇數元素以後),所以須要記錄最後插入的奇數元素的索引。實現代碼以下,算法的時間複雜度是O(n)函數
public int[] reOrderArray(int[] array) { List<int> list = new List<int>(); // 最後插入奇數元素的索引 int index = 0; foreach (int i in array) { if ((i % 2) == 0) list.Add(i); else { list.Insert(index, i); index++; } } return list.ToArray(); }
上面的兩種解法都用到臨時數組或List,空間複雜度是O(n),某些狀況下可能但願空間複雜度越低越好。下面這種解法雖然時間複雜度提升了,但下降了空間複雜度,再也不須要額外的空間。基本思路是遍歷原數組,若是遇到了奇數元素,就將該元素向前移動,該元素前面的偶數元素都依次向後移動。
舉個例子:好比數組{1, 2, 4, 3, 5}
遍歷數組,獲得第一個元素是奇數1,其前面沒有元素因此不作移動
第二個,第三個是偶數,不作處理。
第四個元素是奇數3,因此將3往前移動,3前面的偶數元素{2, 4}
都向後移動。移動後的數組爲{1, 3, 2, 4, 5}
接着第五個元素是奇數5,因此將5往前移動,5前面的偶數元素{2, 4}
都向後移動。移動後的數組爲{1, 3, 5, 2, 4}
能夠這樣理解,每發現一個奇數時,就將這個奇數移動到了它最終應該在的位置上。code
public int[] reOrderArray(int[] array) { for(int i = 0; i < array.Length; i++) { if((array[i] % 2) != 0) { int temp = array[i]; int j = i - 1; for(; j >= 0; j--) { if ((array[j] % 2) != 0) break; array[j + 1] = array[j]; } array[j + 1] = temp; } } return array; }