hot100 |二、双指针

1-leetcode移动零

注意:√

  1. 思路之前见过,不过需要复习
  2. 简单来说就是先把不是0的赶到左边去,然后把后续全部设置为0
    public void moveZeroes(int[] nums) {
        int n = nums.length;
        if (n == 1){
            return;
        }
        int low = 0;
        int high = 0;
        while (high < n){
            if (nums[high] != 0){
                nums[low] = nums[high];
                low++;
            }
            high++;
        }
        for (int i = low; i<n; i++){
            nums[i] = 0;
        }
        
    }

2-leetcode盛最多水的容器

注意:×√

  1. 看了接雨水以后,这个确实要简单一点,注意是矩形面积的计算
    public int maxArea(int[] height) {
        int n = height.length;
        int left = 0;
        int right = n-1;


        int res = 0;
        while (left<right){
            res = Math.max(res, Math.min(height[left], height[right])* (right-left));
            if (height[left] <= height[right]){
                left++;
            }else {
                right--;
            }
        }
        return res;
    }

3-leetcode三数之和

注意:×

  1. 学习的是labuladong的方法,3sum转2sum
  2. 注意要先对数组排序,在2sum中操作的时候要注意int total = nums[low] + nums[high]; int left = nums[low]; int right = nums[high];
  3. 注意整理的left和right用于后续的while判断,一定要注意while判断以后还需要进行指针的移动操作
public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ans = new ArrayList<>();
        Arrays.sort(nums);
        int n = nums.length;
        for (int i = 0; i < n; i++) {
            List<List<Integer>> twoAns = twoSum(nums, i + 1, 0 - nums[i]);
            for (List<Integer> twoAn : twoAns) {
                twoAn.add(nums[i]);
                ans.add(twoAn);
            }
            while (i<n-1 && nums[i] == nums[i+1]){
                i++;
            }
        }
        return ans;
    }

    private List<List<Integer>> twoSum(int[] nums, int start, int target) {
        List<List<Integer>> ans = new ArrayList<>();
        int low = start;
        int high = nums.length - 1;
        while (low<high){
            int total = nums[low] + nums[high];
            int left = nums[low];
            int right = nums[high];
            if (total > target){
                while (low<high && nums[high-1]==right){
                    high--;
                }
                high--;
            } else if (total < target) {
                while (low<high && nums[low+1]==left){
                    low++;
                }
                low++;
            }else {
                List<Integer> an = new ArrayList<>();
                an.add(left);
                an.add(right);
                ans.add(an);
                while (low<high && nums[high-1]==right){
                    high--;
                }
                while (low<high && nums[low+1]==left){
                    low++;
                }
                high--;
                low++;
            }
        }
        return ans;
    }

4-leetcode接雨水

注意:×

  1. 传说中的接雨水,trap1是用的备忘录,trap用的是双指针
  2. 很巧妙的思路,注意base case中的初始值,以及遍历的方向
public int trap1(int[] height) {
        int n = height.length;
        int[] leftMax = new int[n];
        int[] rightMax = new int[n];

        // base case
        leftMax[0] = height[0];
        rightMax[n-1] = height[n-1];
        for (int i = 1; i < n; i++) {
            leftMax[i] = Math.max(leftMax[i-1], height[i]);
        }
        for (int i = n-2; i >= 0; i--) {
            rightMax[i] = Math.max(rightMax[i+1], height[i]);
        }

        int res = 0;
        for (int i = 1; i < n-1; i++) {
            res = res+ Math.min(leftMax[i], rightMax[i])-height[i];
        }
        return res;
    }

        public int trap(int[] height) {
        int n = height.length;
        if (n<3){
            return 0;
        }
        int leftMax = height[0];
        int rightMax = height[n-1];
        int left = 0;
        int right = n-1;

        int res = 0;
        while (left<right){
            leftMax = Math.max(leftMax, height[left]);
            rightMax = Math.max(rightMax, height[right]);

            if (leftMax<rightMax){
                res = res+ leftMax-height[left];
                left++;
            }else {
                res = res + rightMax-height[right];
                right--;
            }
        }
        return res;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值