数组解题之常用方法:双指针、快慢指针

做题的目的是为了强化解题思路和方法的实现,其次是编程能力的提高。不论题目难易,对于每道题,其背后的思想和逻辑都值得我们探究。
剑指offer21:调整数组顺序使奇数位于偶数前面
示例:
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。

这道题是一道简单题,用一句名言就是“这道题我拿到手就会做~”然后,用自己的方法做完之后,我们是不是得思考下有没有其他的方法和这道题的内在逻辑,以后遇到这种题目从哪里下手等等。多思考多总结。
这道题目:本质就是交换数据,判断数据是奇数还是偶数,如果是奇数就放到数组前面,偶数放到数组后面。

方法一:暴力解法,建立一个额外的数组用来存数据,然后遍历数组即可。

 class Solution {
     public int[] exchange(int[] nums) {
         int[] arr = new int[nums.length];
         int left = 0;
         int right = nums.length-1;
         for(int i=0;i<nums.length;i++){
             if(nums[i]%2 != 0){
                 arr[left++] = nums[i];
             }else{
                 arr[right--] = nums[i];
             }
         }
         return arr;
     }
 }

显然这个方法是最笨的,用时也比较长。那我们能不能不用另外建立一个新的数组,直接从原数组下手呢?显然是可以的,第二种方法,我们使用双指针来解决问题。其实方法一,也是用了两个指针,不过这两个指针只是用来只是存放的位置,对于原数组数据的判断没有起到一点作用。
方法二:使用双指针,定义一个left指针执行最左边的位置;定义一个right指针指向最右边的位置。之后左右指针同时移动,由于题目要求是数组前面放奇数,后面放偶数;因此,当左(left)指针遇到偶数时停下来,当右(right)指针遇到奇数时停下来,之后交换左右指针的位置继续移动。

 class Solution{
     public int[] exchange(int[] nums){
         int left = 0;
         int right = nums.length-1;
         while(left < right){
             //当left遇到偶数的时候停,奇数的时候一直走【(nums[left] & 1) == 1 奇数】
             while(left<right && (nums[left] & 1) == 1){
                 left++;
             }
             //当right遇到奇数的时候停止,偶数的时候一直走【(nums[length & 1] == 0)偶数】
             while(left<right && (nums[right] & 1) == 0){
                 right--;
             }
             //交换
             int temp = nums[left];
             nums[left] = nums[right];
             nums[right] = temp;
         }
         return nums;
     }
 }

当然了,我们还有第三种思路去解决这个问题,使用快慢指针,基本思路是快指针fast去寻找奇数,找到奇数时就停下来,和slow指针进行交换(slow指针指向的是偶数)
方法三:快慢指针

class Solution{
    public int[] exchange(int[] nums){
        int slow = 0;
        int fast = 0;
        //用fast指针去找奇数
        while(fast<nums.length){
            if((nums[fast] & 1) == 1){
                //fast找到奇数
                if(slow != fast){
                    int temp =nums[slow];
                    nums[slow] = nums[fast];
                    nums[fast] = temp;
                }
                slow++;
            }
            fast++;
        }
        return nums;
    }
}

在执行效率上,双指针和快慢指针是差不多的,暴力解法很慢。
快慢指针和双指针用的还是挺多的,他们之间的区别是:双指针是两边开始;快慢指针是同一边开始,两个指针快慢不一样。快慢指针还可以用于找数组的中间位置元素,比如慢指针走一步,快指针都两步,当快指针走到最后一个元素时,慢指针正好指向中间位置的元素。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值