剑指offer:调整数组顺序使奇数位于偶数前面
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分.
解题思路
- 维护两个指针,一个从头开始另一个从尾部开始,交换两指针的奇偶数,指针相遇则停止。
int i=0; int j=array.length-1; while(i<j){ // 向后移动,直到它指向偶数 while(i<j&&array[i]%2==1){ i++; } // 向前移动,直到它指向奇数 while(i<j&&array[j]%2==0){ j--; } int temp=array[j]; array[j]=array[i]; array[i]=temp; }
- 考虑可扩展的解法,将判断标准单独解耦出来,提高代码的重用性
int i=0; int j=array.length-1; while(i<j){ // 向后移动,直到它指满足标准 while(i<j && !func(array[i])){ i++; } // 向前移动,直到它指满足标准 while(i<j && func(array[j])){ j--; } int temp=array[j]; array[j]=array[i]; array[i]=temp; } 考虑到扩展性是一个经验丰富的程序员必需要考虑到的事情,因为解耦可以提高代码的重用性,为功能扩展提供了便利。
题型扩展
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
解题思路
一旦需要保证相对位置不变,那么前面的方法都不满足条件了。
- 类似于插入排序,不使用额外空间,从头到尾遍历,如果是奇数,那就往前找一段连续的偶数,然后与该段偶数交换位置。时间复杂度接近O(n^2)
public class Solution { public void reOrderArray(int [] array) { for (int i=0; i<array.length; i++){ // 使用位与运算代替求余,判断是否为奇数 if ((array[i]&1)==1){ int temp = array[i]; int j = i - 1; // 往前找一段偶数,保证顺序 while(j>=0 && (array[j]&1)==0){ array[j+1] = array[j]; j --; } // 该奇数与该段偶数交换 array[j + 1] = temp; } } } }
- 使用额外空间,新建一个数组先把原数组中的奇数push进去再把偶数push进去,然后用新数组数据覆盖原数组即可,时间复杂度O(n),空间复杂度为O(n)
public class Solution { public void reOrderArray(int [] array) { int[] arrayTemp = new int[array.length]; int index = 0; for (int i: array){ if((i&1)==1) arrayTemp[index++] = i; } for (int j: array){ if((j&1)==0) arrayTemp[index++] = j; } for (int x=0; x<array.length; x++){ array[x] = arrayTemp[x]; } } }
浙公网安备 33010602011771号