双指针的妙用

算法通关村 —— 双指针的妙用

本文针对数组删除的元素的场景,提供一些解决的方法

  • 原地删除数值等于val的值
  • 删除有序数组中的重复项

原地删除数值等于val的值

        问题描述:提供一个数组array和一个值val,将数组中的val值移除并最后返回数组长度(不使用O(1)的额外空间,数组的顺序可以改变)

         解决思路:

         1、快慢指针

         在数组头部设置俩指针,快指针每次+1,慢指针在array[slow] != val时+1,当array[fast] != val时,array[fast] 和 array[slow]对调;

    /**
     * 快慢指针,快指针每次加1,慢指针在array[fast] != val时加1
     * 当array[fast] != val时,array[slow] = array[fast]
     */
    public static int slowFastPoint(int[] array, int val) {
        int slow = 0;
        for (int fast = 0; fast < array.length; fast++) {
            if (array[fast] != val) {
                array[slow] = array[fast];
                slow++;
            }
        }
        return slow;
    }
        2、对撞指针

        设置两指针left、right分别向中间靠拢(移动一步),当array[right] != val、array[slow] = val

时,双方互换,依次类推;

     /**
     * 对撞指针,快指针从最后出发,慢指针从头开始
     * 快指针遇到非val时停下,当slow遇到val时,与fast交换,以此类推
     */
    public static int collisionPoint(int[] array, int val) {
        int left = 0;
        int right = array.length - 1;
        while (left <= right) {
            if (array[right] != val && array[left] == val) {
                array[left] = array[right];
                array[right] = val;
            }
            if (array[right] == val) right--;
            if (array[left] != val) left++;
        }
        return left;
    }

        

        3、对撞指针+覆盖

        该思路也是设置left、right两指针同时靠拢,当array[left] = val 时直接与array[right]对换,此时left先不+1,而是判断交换过来的val是否等于val,再重复上步骤;

   /**
     * 双碰撞指针,array[left] == val时,直接array[left] = array[right],但赋值后还是从当前开始
     */
    public static int cover(int[] array, int val) {
        int left = 0;
        int right = array.length - 1;
        while (left <= right){
            if (array[left] == val){
                array[left] = array[right];
                right--;
            }else {
                left++;
            }
        }
        return right + 1;
    }

        

删除有序数组中的重复项

        问题描述:提供一个有序数组array,删除数组中重复的元素,返回最终的数组长度;(仅能用O(1)的额外空间)

        

        解决思路:

        还是使用双指针的来解决问题,slow和fast依次加1,当array[slow] = array[fast]时,slow停下,直到array[fast] != array[slow],两值互换,然后各移一步,继续上述操作;


    /**
     * 删除有序数组中的重复项
     * */
    public static int removeDuplicate(int[] array){
        int slow = 1;
        for (int fast = 0; fast < array.length; fast++) {
            if (array[fast] != array[slow - 1]){
                array[slow] = array[fast];
                slow++;
            }
        }
        return slow;
    }

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值