LeetCode-剑指Offer-21-调整数组顺序使奇数位于偶数前面


题意描述:

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

提示:

  • 1 <= nums.length <= 50000
  • 1 <= nums[i] <= 10000

示例:

一:

输入:nums = [1,2,3,4]
输出:[1,3,2,4] 
注:[3,1,2,4] 也是正确的答案之一

解题思路:

Alice: 有点像快速排序里面的思想呀,用两个双指针,一个从前往后找偶数,一个从后往前找奇数,找到了就交换,一次让两个数字回归正常的位置,然后重复,直到两个指针相遇。
Bob: 对对对,这样应该是最快的写法了吧。
Alice: 面试的时候还要再确认一下是不是可以修改参数数组,如果不是的话,那就可在复制数组的时候直接分来了,也用双指针。
Bob: o( ̄▽ ̄)d


代码:

Python 方法一: 双指针

class Solution:
    def exchange(self, nums: List[int]) -> List[int]:
        left = 0
        right = len(nums)-1
        while left < right:

            while left < right:
                if nums[left] % 2 == 0:
                    break
                left += 1
            
            while left < right:
                if nums[right] % 2 == 1:
                    break
                right -= 1
            
            nums[left], nums[right] = nums[right], nums[left]
            left  += 1
            right -= 1

        return  nums

Python 方法二: 使用两个数组存放奇数和偶数,最后合并。

class Solution:
    def exchange(self, nums: List[int]) -> List[int]:
        
        tmp_odd  = []
        tmp_even = []

        for x in range(len(nums)):
            if nums[x] % 2 == 0:
                tmp_even.append(nums[x])
            else:
                tmp_odd.append(nums[x])

        return tmp_odd + tmp_even

Java 方法一:双指针

class Solution {
    public int[] exchange(int[] nums) {
        int left  = 0;
        int right = nums.length - 1;
        while(left < right){
            // 在左侧找到一个偶数
            while(left < right){
                if(nums[left] % 2 == 0){
                    break;
                }
                left ++;
            }
            // 在右侧找到一个奇数
            while(left < right){
                if(nums[right] % 2 == 1){
                    break;
                }
                right --;
            }

            // 交换这两个数
            int tmp = nums[left];
            nums[left] = nums[right];
            nums[right] = tmp;

            left  ++;
            right --;
        } 
        return nums;
    }
}

Java 方法二:使用数组 + 双指针。

class Solution {
    public int[] exchange(int[] nums) {

        int[] ret = new int[nums.length];    // 用来存储最后的结果
        int left  = 0;
        int right = nums.length-1;           // 双指针

        for(int i=0; i<nums.length; ++i){    // O(n)时间复杂度
            if(nums[i] % 2 == 0){
                ret[right--] = nums[i];
            }else{
                ret[left++] = nums[i];
            }
        }
        return ret;
    }
}

易错点:

  • 一些测试用例:
[1]
[2]
[2,1]
[1,1,3,5]
[1,1,2,3,5]
  • 答案:
[1]
[2]
[1,2]
[1,1,3,5]
[1,1,5,3,2]

总结:

  • 其实这道题有点像 快速排序 的思路。

你可能感兴趣的:(#,剑指Offer)