剑指offer面试题[14]-调整数组顺序使奇数位于偶数前面

题目描述

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变

分析:

        这个题目的最早版本应该是输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分。(没有要求相对位置不变)

        早期版本思路一:

        可以定义一个与原数组大小一样的新数组,遍历原数组,将奇数按顺序从前往后存取到新数组中,若遇到偶数,则从新数组的最后一个位置开始存,遇到第二个偶数,存到新数组倒数第二个位置............依次进行。这种方法空间复杂度为O(n),即需要额外开辟一个新的空间,而且只能保证奇数的相对位置不变,偶数的相对为位置被改变了。因此这种做法是不稳定的。

            早期版本思路二:

         可以定义两个指针,第一个指针从前往后遍历直到遇见第一个偶数,第二个指针从后往前遍历,直到遇见第一个奇数,此时交换两个指针指向数组位置的值,依次移动两个指针,直到两个指针的位置相差1停止。这种做法也只能保证奇数放在前半部分,偶数放在后半部分。并不能保证相对位置不变。

         若要保证相对位置不变,思路如下:

         从数组第一个位置往后依次遍历,遇到第一个偶数暂停,此时下标位置记为i,然后从位置i+1开始,依次往后遍历,直到遇见第一个奇数,此时位置为j。用一个临时变量temp将第j个位置的值存起来,然后将数组第i个位置到第j-1个位置依次往后挪动一个位置,最后将temp变量的值,也就是挪动前j位置的值赋给第i个位置,然后执行i++,依次进行下去。。。

                 以1,2,3,4,5,6,7为例分析。

                                                    1    2    3   4   5   6   7

  第一次i和j指向:                             i      j

                  挪动:                        1  3     2   4   5   6   7

  执行i++ :                                  1    3    2   4   5   6   7

                                                                i

第二次i和j指向:                           1    3    2   4   5   6   7

                                                                i          j

                   挪动:

                                                     1    3    5   2   4   6   7

依次执行.........................

参考程序:

class Solution {
public:
    void reOrderArray(vector &array) {
        int n=array.size( );
        if(n==0||n==1)
            return;
        for(int i=0;i           {
             if(array[i]%2==0)                //一定注意是%(取余运算),而不是/(取整)。
                 {
                    for(int j=i+1;j第二处for循环

                        {
                           if(array[j]%2!=0)
                               {
                                   int temp=array[j];
                                   for(int k=j;k>i;k--)
                                      {
                                         array[k]=array[k-1];
                                      }
                                   array[i]=temp;
                               }
                           if(array[i]%2!=0)            //如果j找到了第一个奇数就执行break,否则继续找,因为若没有找到i后面第一个奇数,array[i]的值是偶数,
                               {                               //并没有被改变,当然if判断里面也可以是if(array[j]%2==0)   等 
                                   break;          //这里break的目的是为了j找到第一个奇数后,挪动了相应的元素后退出第二处for循环,而不是依次执行下去
                               }                       //如果是直接是break没有if判断,就会有问题,因为会导致j第一次没有找到奇数就退出了

                        }
                 }
          }
        
    }
};



你可能感兴趣的:(剑指offer)