输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得全部的奇数位于数组的前半部分,全部的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。算法
最直接的思路是再构建一个新数组,先遍历一遍原数组,把其中的奇数依次添加到新数组中,再遍历一遍原数组把其中的偶数依次添加到新数组中,时间复杂度为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; }