双指针| Java | (hot100) 力扣283, 11, 15, 42做题总结

leetcode 11 盛最多水的容器

双层for循环暴力

  • 超出时间限制
java 复制代码
class Solution {
    public int maxArea(int[] height) {
        int h=0;
        int v=0;
        for(int i=0; i<height.length; i++) {
            for(int j=i+1; j<height.length; j++) {
                h = Math.min(height[i],height[j]);
                v = Math.max(v, h*(j-i));
            }
        }
        return v;
    }
}

双指针

设两指针 i , j ,指向的水槽板高度分别为 h[i] , h[j] ,此状态下水槽面积为 S(i,j) 。由于可容纳水的高度由两板中的 短板 决定,因此可得如下 面积公式 S(i,j)=min(h[i],h[j])×(j−i)

在每个状态下,无论长板或短板向中间收窄一格,都会导致水槽 底边宽度 −1​ 变短:

若向内 移动短板 ,水槽的短板 min(h[i],h[j]) 可能变大,因此下个水槽的面积 可能增大 。

若向内 移动长板 ,水槽的短板 min(h[i],h[j])​ 不变或变小,因此下个水槽的面积 一定变小 。

java 复制代码
class Solution {
    public int maxArea(int[] height) {
        int i=0,j=height.length-1;
        int res=0;
        while(i<j) {
            //体积
            res = Math.max(res, Math.min(height[i],height[j])*(j-i));
            if(height[i] < height[j]) {
                i++;
            } else {
                j--;
            }
        }
        return res;
    }
}

leetcode 283 移动零

  • 双指针
    第三次了,终于一次做对
java 复制代码
class Solution {
    public void moveZeroes(int[] nums) {
        int x=0;
        for(int i=0; i<nums.length; i++) {
            if(nums[i] != 0) {
                nums[x++] = nums[i];
            }
        }
        for(int i=x; i<nums.length; i++) {
            nums[i] = 0;
        }
    }
}

leetcode 15 三数之和

  • 不记得思路了!!其实本质还是3层for循环,然后用双指针降低时间复杂度。

出错点

① 必须要写 left<right,因为后面nums[left] nums[right]会边界溢出

② left++ right--必须要加

java 复制代码
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ans = new ArrayList<>();
        Arrays.sort(nums);
        int left,right,sum;
        for(int i=0; i<nums.length; i++) {
            if(nums[i] > 0) return ans;

            if(i>0 && nums[i] == nums[i-1]) continue;

            left = i+1;
            right = nums.length-1;
            while(left < right) {
                sum = nums[i]+nums[left]+nums[right];
                if(sum > 0) {
                    right--;
                } else if(sum < 0) {
                    left++;
                } else {
                    List<Integer> list = new ArrayList<Integer>();
                    list.add(nums[i]);
                    list.add(nums[left]);
                    list.add(nums[right]);
                    ans.add(list);
                    //  ans.add(Arrays.asList(nums[i], nums[left], nums[right]));
		         // 去重逻辑应该放在找到一个三元组之后,对b 和 c去重
                    //去重
                    while(left<right && nums[left+1]==nums[left]) left++;
                    while(left<right && nums[right-1]==nums[right]) right--;

                    left++;
                    right--;
                }
            }
        }
        return ans;
    }
}

二数之和

java 复制代码
class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
        int[] ans = new int[2];
        for(int i=0; i<nums.length; i++) {
            if(map.containsKey(target-nums[i])) {
                ans[0] = map.get(target-nums[i]);
                ans[1] = i;
                break;
            }
            map.put(nums[i], i);
        }
        return ans;
    }
}

四数之和

  • 和三数之和差不多,但忘记怎么写了
java 复制代码
class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        int left=0,right=0;
        long sum=0;
        for(int i=0; i<nums.length; i++) {
            //i去重
            if(i>0 && nums[i]==nums[i-1]) continue;
            for(int j=i+1; j<nums.length; j++) {
                if(j>(i+1) && nums[j]==nums[j-1]) continue;
                left=j+1;
                right=nums.length-1;
                while(left<right) {
                    sum = (long)nums[i]+nums[j]+nums[left]+nums[right];
                    if(sum > target) {
                        right--;
                    } else if(sum < target) {
                        left++;
                    } else {
                        List<Integer> list = new ArrayList<>();
                        list.add(nums[i]);
                        list.add(nums[j]);
                        list.add(nums[left]);
                        list.add(nums[right]);
                        res.add(list);

                        // left right 去重
                        while(left<right && nums[left+1]==nums[left]) left++;
                        while(left<right && nums[right-1]==nums[right]) right--;

                        left++;
                        right--;
                    }
                }
            }
        }
        return res;
    }
}

leetcode 42 接雨水

  • zhe
相关推荐
一点程序11 分钟前
基于SpringBoot的选课调查系统
java·spring boot·后端·选课调查系统
C雨后彩虹13 分钟前
计算疫情扩散时间
java·数据结构·算法·华为·面试
2601_9498095917 分钟前
flutter_for_openharmony家庭相册app实战+我的Tab实现
java·javascript·flutter
vx_BS813301 小时前
【直接可用源码免费送】计算机毕业设计精选项目03574基于Python的网上商城管理系统设计与实现:Java/PHP/Python/C#小程序、单片机、成品+文档源码支持定制
java·python·课程设计
2601_949868361 小时前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
醉颜凉1 小时前
【LeetCode】打家劫舍III
c语言·算法·leetcode·树 深度优先搜索·动态规划 二叉树
达文汐1 小时前
【困难】力扣算法题解析LeetCode332:重新安排行程
java·数据结构·经验分享·算法·leetcode·力扣
一匹电信狗1 小时前
【LeetCode_21】合并两个有序链表
c语言·开发语言·数据结构·c++·算法·leetcode·stl
User_芊芊君子1 小时前
【LeetCode经典题解】搞定二叉树最近公共祖先:递归法+栈存路径法,附代码实现
算法·leetcode·职场和发展
培风图南以星河揽胜1 小时前
Java版LeetCode热题100之零钱兑换:动态规划经典问题深度解析
java·leetcode·动态规划