题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序使得所有奇数位于前面半部分,偶数位于后半部分。
分析:
1. 方案一:最朴素做法是枚举数组,发现一个奇数就把数字放到前面,然后移到后面的数字。时间复杂度为O(n^2)
2. 方案二:最常用的的双指针法,设置两个指针p1,p2初始化指向数组的第一个数和数组的最后一个数。
总的由以下四种情况
(1)如果p1指向的数为奇数则p1向后移到一位,如果p2指向的数是偶数则p2向前移到一位。
(2)如果p1指向的数为奇数则p1向后移到一位,如果p2指向的数为奇数则p2不变。
(2)如果p1指向的数为偶数,p2指向的数是奇数;则此时把p1和p2两个值交换,p1向后移到一位p2向前移到一位
(3)如果p1指向的数为偶数,p2指向的数是偶数;则p1不变p2往前移到一位。
方案二,设置两个指针直到两个指针指向同一个位置结束,时间复杂度为O(n)
举例:数组{2,0,1,3,4,5}
(1)第一次数组如下所示,发现p1指向为偶数p2指向为奇数,则交换p1和p2的值
(2)第二次如图所示,发现p1指向的值为偶数则p1不变,p2指向为偶数,则p2向前移到一位
(3)第三次如图所示 ,p1指向偶数,p2指向奇数则p1和p2值交换,p1向后移到一位,p2向前移到一位
(4)第四次如图所示,发现p1和p2指向同一位置,说明以及把数组调整为奇数在前偶数在后
代码:
#include<iostream> #include<algorithm> using namespace std; //把奇数放到偶数前面 void ReOrderArr(int *arrNum, int n){ //数据不合法 if(arrNum == NULL || n <= 0){ return; } int left = 0; int right = n-1; while(left < right){ //left指向数为奇数 if(arrNum[left]&1 == 1){ ++left; //如果right指向的数为偶数 if(arrNum[right]&1 == 0){ --right; } } else{ //如果right指向的数为奇数 if(arrNum[right]&1 == 1){ swap(arrNum[left++], arrNum[right--]); } else{ --right; } } } } int main(){ int arrNum[] = {2,0,1,3,4,5}; ReOrderArr(arrNum, 6); //test for(int i = 0; i < 6; i++){ cout<<arrNum[i]<<endl; } return 0; } /* 输出 5 3 1 0 4 2 */