230730-czl-leeetcode双指针专题

双指针专题

双指针法:

广泛使用在数组 链表 字符串移除,交换场景

  • 同向双指针
  • 相向双指针

本篇主要是双指针在数组中的用法

同向双指针

定义快慢两个指针

  • 快指针:遍历整个集合,进行一些规则匹配
  • 慢指针:代表当前符合条件的集合
对数组操作:题目关键词 原地不使用额外空间

27. 移除元素

定义快慢两个指针,快指针遍历整个数组的元素

  • 如果 不等于 val 的元素,交换 fast 和slow 对应的下标,并且慢指针移动一位;

  • 如果相等,继续查看下一个。

    最后结果返回慢指针的下标即可

    public int removeElement(int[] nums, int val) {
            int slow = 0 ;
            for(int fast =0;fast<nums.length;fast++ ){
                if(nums[fast]!=val){
                    int temp = nums[fast];
                    nums[fast] = nums[slow];
                    nums[slow] = temp;
                    slow++;
                }
            }
            return slow;
    }

26. 删除有序数组中的重复项

这个题比较对象是 nums[slow] 和 nums[fast].

fast 遍历整个数组,slow指示整个

  • 相同 fast ++;

  • 不相同,num[++slow] = num[fast]

代码

 public int removeDuplicates(int[] nums) {
        if(nums == null || nums.length ==0){
            return 0;
        }
        int slow = 0;
        for(int fast = 0;fast<nums.length;fast++){
            if(nums[fast]!=nums[slow]){
                slow++;
                nums[slow] = nums[fast];
            }


        }
        return slow+1;
    }

283. 移动零

本题思路类似:27. 移除元素

fast寻找下一个不等于 零的数

相等:fast++;

不相等:交换 fast 和slow 对应的下标,并且slow 后移

    public void moveZeroes(int[] nums) {
        if( nums==null || nums.length == 0|| nums.length==1){
            return ;
        }
        int slow =0;
        for(int fast = 0;fast<nums.length;fast++){
            if(nums[fast]!=0){
                int temp = nums[fast];
                nums[fast] = nums[slow];
                nums[slow] = temp;
                slow++;
            }
        }
    }

相向双指针

双指针 一般是一个在开头,一个在结尾,两者相向处理问题

977. 有序数组的平方

可以先全部求平方,然后再重新升序排列即可

但是可以借助 负数平方之后不一定比正数平方之后小 使用左右指针,开始判断

  • 如果 nums[left]的平方 < nums[right] 的平方 ,将 right对应的平方放到结果数组中,right 减一

  • 如果 nums[left]的平方 >= nums[right] 的平方 ,将 left 对应的平方放到结果数组中,left +1

    public int[] sortedSquares(int[] nums) {
        if(nums.length == 0 || nums==null){
            return new int[0];
        }

        int size = nums.length;
        int left = 0;
        int right = size-1;
        
        int[] res = new int[size];
        int index = size-1;
        while(left<=right){
            int leftVal= nums[left] * nums[left];
             int rightVal = nums[right] * nums[right];
            if(leftVal >=rightVal  ){
                res[index--] = leftVal;
                left++;
            }else{
                res[index--] = rightVal;
                right--;
            }
        }
        return res;
    }

941. 有效的山脉数组

分别从左右两边进行判断,直到不满足条件为止

最后比较看left和right

  • left==right

  • left !=0;

  • right != nums.length -1

    上面三点都满足说明是山脉。如果left或者right都在起始位置,说明不是山峰

注意这里还是有一些细节,例如如下两点:
  • 因为left和right是数组下标,移动的过程中注意不要数组越界
  • 如果left或者right没有移动,说明是一个单调递增或者递减的数组,依然不是山峰
  public static boolean validMountainArray(int[] arr) {
      //特殊值判断      
      		if(arr.length<3){
                return false;
            }
            int size = arr.length;
            int left = 0;
            int right = size-1;
      		 // 注意防止越界
            while(left+1 < size && arr[left]<arr[left+1]){
                left++;
            }
       		// 注意防止越界
            while(right-1 > 0 && arr[right-1 ] > arr[right]){
                right--;
            }
        // 如果left或者right都在起始位置,说明不是山峰
            if(right==left && left!=0 && right!=size-1){
                return true;
            }
            return false;

        }

844. 比较含退格的字符串

重构字符串法

使用StringBuilder动态的拼接字符串

如果是字符就拼接上

如果是 # 就删除掉最后一个,但是要小心 # 太多导致删除的时候越界

双指针法

逆序操作

    }

[844. 比较含退格的字符串](https://leetcode.cn/problems/backspace-string-compare/)

**重构字符串法**

使用StringBuilder动态的拼接字符串

如果是字符就拼接上

如果是 # 就删除掉最后一个,但是要小心 # 太多导致删除的时候越界

**双指针法**

逆序操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值