【算法】调整数组顺序使奇数位于偶数前面

194 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情

题目

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。

解题思路

题目要求把奇数放在数组前半部分,偶数放在数组后半部分,需要遍历数组中元素将奇数全部移动到前面即可(无需考虑元素数字排序问题)。

双指针解法

定义两个指针:i,j两个分别用于寻找偶数和奇数值。

  1. 第一个指针初始化指向数组第一个数值,第二个指针初始化指向数组最后一个数值。
  2. 第一个指针向前移动,第二个指针向后移动,当第一个指针找到偶数时停下同理第二个指针找到奇数数时停下。
  3. 当双指针都满足要求找到满足条件后值做交换。
  4. 直到双指针重合为止(替换完毕)。
    public int[] exchange(int[] nums) {
         int i = 0;
         int j = nums.length - 1;
         while(i < j){
             int left = nums[i];
             int right = nums[j];
             if(left % 2 == 0 && right % 2 != 0){
                 nums[j] = left;
                 nums[i] = right;
                 i++;
                 j--;
             }
             if(left % 2 != 0)  i++; // 奇数右移
             if(right % 2 == 0) j--; // 偶数左移
         }
         return nums;
    }

双指针解法可以想到之前做的另外一道题目:旋转数组的最小值 同样是运用双指针首尾往内合并(二分法)找到最小值,解法使用方法存在相似性。

双指针进阶解法

既然是双指针找到对应满足条件的值,那么就可以先循环一遍的值再循环另外一边(只要在限定条件内即可)。同理当本题目修改条件后同样也能满足要求,比如把奇数偶数判断条件修改为是否可被3整除,又或者是否为负数等条件只需要将如下代码中 while(nums[i] % 2 != 0 && i < j)while(nums[j] % 2 == 0 && i < j)条件替换一下即可。

 public int[] exchange(int[] nums) {
      int i = 0;
      int j = nums.length - 1;
      while(i < j){
          while(nums[i] % 2 != 0 && i < j) i++;  // 条件封装
          while(nums[j] % 2 == 0 && i < j) j--;  // 条件封装
          int temp = nums[j];
          nums[j] = nums[i];
          nums[i] = temp;
          i++;
          j--;
         
      }
      return nums;
 }