LeetCodeHot100 双指针 283. 移动零 11. 盛最多水的容器 15. 三数之和 42. 接雨水

283. 移动零
https://leetcode.cn/problems/move-zeroes/description/?envType=study-plan-v2&envId=top-100-liked

public void moveZeroes(int[] nums) {
        int r = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] != 0){
                int temp = nums[r];
                nums[r] = nums[i];
                nums[i] = temp;
                r++;
            }
        }
    }

总结:一个指针去记录放非0的位置,一个指针去遍历
11. 盛最多水的容器
https://leetcode.cn/problems/container-with-most-water/description/?envType=study-plan-v2&envId=top-100-liked

public int maxArea(int[] height) {
        int i = 0 , j = height.length - 1;
        int maxRain = 0;
        while (i < j){
            maxRain = height[i] < height[j] ? 
                    Math.max(maxRain , getRain(height ,i++,j)) :
                    Math.max(maxRain , getRain(height,i,j--));
        }
        return maxRain;
    }
    public int getRain(int[] height, int i,int j){
        return (j - i) * Math.min(height[i],height[j]);
    }

总结:使用双指针,总体思想就是先让指针在左右边界,然后每次指针往里收缩,收缩哪个呢,收缩二者矮的那个,因为收缩矮的,下个面积可能变大,如果收缩高的,下个面积不变(收缩了之后高度一样)或变小(收缩之后高度变小)(ps:如果收缩之后高度变大了,由于有之前的短板的存在,所以木桶效应,还是面积会变小)
15. 三数之和
https://leetcode.cn/problems/3sum/description/?envType=study-plan-v2&envId=top-100-liked

public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);
        List<List<Integer>> resList = new ArrayList<>();
        for (int k = 0; k < nums.length - 2; k++) {
            if (nums[k] > 0) break;
            if (k > 0 && nums[k] == nums[k-1]) continue;
            int i = k + 1 , j = nums.length - 1;
            while (i < j){
                int sum = nums[k] + nums[i] + nums[j];
                if (sum > 0){
                    do{
                        j--;
                    }while (i < j && nums[j] == nums[j+1]);
                }else if (sum < 0){
                    do {
                        i++;
                    }while (i < j && nums[i] == nums[i-1]);
                }else {
                    resList.add(new ArrayList<Integer>(Arrays.asList(nums[k],nums[i],nums[j])));
                    do{
                        j--;
                    }while (i < j && nums[j] == nums[j+1]);
                    do {
                        i++;
                    }while (i < j && nums[i] == nums[i-1]);
                }
            }
        }
        return resList;
    }

总结:关键点在于去重,这里使用的方法就是先排序了,排序之后通过指针可以很好解决去重(发现和上一个重复就再往中间移动), 最后犹豫不决先排序,步步逼近双指针!
42. 接雨水
https://leetcode.cn/problems/trapping-rain-water/description/?envType=study-plan-v2&envId=top-100-liked

public int trap(int[] height) {
        int rain = 0;
        // 左右指针:分别指向左右两边界的列
        int left = 0;
        int right = height.length - 1;
        // 左指针的左边最大高度、右指针的右边最大高度
        int leftMax = height[left];
        int rightMax = height[right];
        // 最两边的列存不了水
        left++;
        right--;
        // 向中间靠拢
        while (left <= right){
            leftMax = Math.max(leftMax,height[left]);
            rightMax = Math.max(rightMax,height[right]);
            if (leftMax <= rightMax){
                // 左指针的leftMax比右指针的rightMax矮
                // 说明:左指针的右边至少有一个板子 > 左指针左边所有板子
                // 根据水桶效应,保证了左指针当前列的水量决定权在左边
                // 那么可以计算左指针当前列的水量:左边最大高度-当前列高度
                rain += leftMax - height[left];
                left++;
            }else {
                // 右边同理
                rain += rightMax - height[right];
                right--;
            }
        }
        return rain;
    }

总结:核心思想就是上面注释中说的那样,左最高和右最高,若从左往右遍历的话 会更新左最高,此时如果右最高比左最高大就说明这一列肯定有水,就加进去即可 这道题我会每天复习一遍

posted @   jeasonGo  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示