首页 > 其他分享 >hot100-一刷-02双指针(共4道题)

hot100-一刷-02双指针(共4道题)

时间:2024-12-01 20:34:35浏览次数:4  
标签:02 道题 nums int height length right hot100 left

283. 移动零

题目链接

题目描述

image

代码实现

分析:
快慢指针,快指针指向不为0的数,慢指针指向左边当前已经处理好的序列的尾部

代码:

class Solution {
    public void moveZeroes(int[] nums) {
        int slow = 0;
        int fast = 0;
        int n = nums.length;
        while(fast < n){
            if(nums[fast] != 0){
                int temp = nums[slow];
                nums[slow] = nums[fast];
                nums[fast] = temp;
                slow++;
            }
            fast++;
        }
    }
}

11. 盛最多水的容器

题目链接

题目描述

image

代码实现

分析:

  • 暴力做法,两个for循环,依次遍历每两个柱子之间的面积,注意这里题目说的意思是选定了两个柱子,其它柱子就没有。

    点击查看代码,暴力会超时!
    class Solution {
    	public int maxArea(int[] height) {
    		int area = 0;
    		for (int i = 0; i < height.length; i++) {
    			for (int j = i + 1; j < height.length; j++){
    				int areat= Math.min(height[i], height[j]) * (j-i);
    				area = Math.max(area, areat);
    			}
    		}
    		return area;
    	}
    }
    
  • 双指针:有点像贪心,left 和 right 一定是选最小的那个值作为高度,假设宽度为t (下标之差), 那么假设left是最小的,它的面积就是height[left] * t, 再往后,就算right左边还有更高的,面积也是不可能大于height[left] * t的。因为,首先,t就变小了,t-1或者更小。 其次,如果right左边有更低的,比left还低,那面积肯定就更小了。所以这个left就可以舍去了,或者说,最小值的那条边剩余情况就可以舍去了,不用再考虑了。

代码:

class Solution {
    public int maxArea(int[] height) {
        int area = 0;
        int left = 0;
        int right = height.length - 1;
        while (left < right){
            int min = Math.min(height[left], height[right]);
            int areaTemp = min * (right - left);
            area = Math.max(area, areaTemp);
            if(min == height[left]) {
                left++;
            }else {
                right--;
            }
        }
        return area;
    }
}

15. 三数之和

题目链接

题目描述

image

代码实现

分析:
注意去重

代码:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums); // 自然排序,升序
        for (int i = 0; i < nums.length; i++){
            // 对第一个元素去重
            if(i > 0 && nums[i] == nums[i-1]){
                continue;
            }

            int left = i + 1;
            int right = nums.length - 1;
            while(left < right){
                int sum = nums[left] + nums[right];
                if (sum < 0 - nums[i]){
                    left++;
                }else if(sum > 0 - nums[i]){
                    right--;
                }else { // 相等,找到一组   
                    List<Integer> list = new ArrayList<>();
                    list.add(nums[i]);
                    list.add(nums[left]);
                    list.add(nums[right]);
                    res.add(list);
                    // 对第二个元素去重
                    while(left < right && nums[left] == nums[left + 1]) left++;
                    // 对第三个元素去重
                    while(left < right && nums[right] == nums[right - 1]) right--;
                    left++;
                    right--;
                }
            }
        }
        return res;
    }
}

42. 接雨水

题目链接

题目描述

image

代码实现

分析:
最关键是要找到对于每个柱子来说,它左边的 最大值 和右边的 最大值,两者取最小值,再减去柱子的值,就是它自己可以接的水。纯暴力的话就是要对每个柱子都计算出来
image

  • 分析讲解视频

  • 单调栈解法 横着计算 单调栈详解

    点击查看代码
    class Solution {
    	public int trap(int[] height) {
    		Deque<Integer> stack = new LinkedList<>();
    		int res = 0;
    		// 单调栈
    		// 从左到右, 遇到高的柱子,就可以计算含水量了
    		stack.push(0);
    		for(int i = 1; i < height.length; i++){
    			if(height[i] < height[stack.peek()]){
    				stack.push(i);
    			}else if(height[i] == height[stack.peek()]){
    				stack.pop();
    				stack.push(i);
    			}else {  // height[stack.peek()] < height[i]
    				while(!stack.isEmpty() && height[stack.peek()] < height[i]){
    					int mid = stack.pop();
    				   if(!stack.isEmpty()){
    						int left = stack.peek();
    						int right = i;
    						int cnt = Math.min(height[left], height[right]) - height[mid];
    						System.out.println(cnt * (right - left -1));
    						res += cnt * (right - left -1);
    				   }
    				}
    				stack.push(i);
    			}
    		}
    		return res;
    	}
    }
    
  • 前后缀分解 竖着计算

    点击查看代码
    class Solution {
    	public int trap(int[] height) {
    		int[] pre = new int[height.length];
    		int[] suf = new int[height.length];
    		int ans = 0;
    		pre[0] = height[0];
    		for(int i = 1; i < height.length; i++){
    			pre[i] = Math.max(pre[i-1], height[i]);
    			System.out.print(pre[i]);
    		}
    		suf[height.length -1] = height[height.length-1];
    		for(int i = height.length -2; i >= 0; i--){
    			suf[i] = Math.max(suf[i+1], height[i]);
    		}
    		for(int i = 0; i < height.length; i++){
    			ans += Math.min(suf[i], pre[i]) - height[i];
    		}
    		return ans;
    	}
    }
    
  • 双指针 竖着计算
    这里说的前缀后缀可以想象成木板的长度。
    preMax 记录着到达 left 的最大前缀,sufMax 记录着到达 right 的最大后缀,找到当前,preMax 和 sufMax 的最小值。
    比如,当 preMax 比 sufMax 小的时候,对于 left 来说,它的后缀一定是大于等于这个时候的 sufMax 的,而它的前缀最大也知道了,就是当前的 preMax。
    同理,对于right来说,当 sufmax<preMax 的时候,说明它的前缀一定是大于等于这个时候的 preMax,而它的后缀最大也知道了,就是当前的 sufMax,自然可以计算。
    sufmax 和 preMax 相等的时候就无所谓哪个加了。

代码:

class Solution {
    public int trap(int[] height) {
        int n = height.length;
        int left =0;
        int right = n-1;
        int preMax = 0;
        int sufMax = 0;
        int ans = 0;

        while(left < right){
            preMax = Math.max(preMax, height[left]);
            sufMax = Math.max(sufMax, height[right]);
            // 找到小的那边,小的那边说明已经确定可以装多少水了
            if (preMax < sufMax){
                ans += preMax - height[left];
                left++;
            }else {
                ans += sufMax - height[right];
                right--;
            }
        }
        return ans;
    }
}

标签:02,道题,nums,int,height,length,right,hot100,left
From: https://www.cnblogs.com/chendsome/p/18579942

相关文章

  • 20222303 2024-2025-2 《网络与系统攻防技术》实验七实验报告
    1.实验内容应用SET工具,通过多步操作建立冒名网站,获取登录信息。利用ettercap实施DNSspoof攻击,篡改特定网站IP。结合两种技术,用DNSspoof引导访问至冒名网站。2.实验过程2.1简单应用SET工具建立冒名网站输入命令sudovi/etc/apache2/ports.conf查看本机apache......
  • 2024-12-01:单面值组合的第 K 小金额。用go语言,给定一个整数数组 coins,表示不同面值的
    2024-12-01:单面值组合的第K小金额。用go语言,给定一个整数数组coins,表示不同面值的硬币,同时给出一个整数k。你可以使用任意数量的这些硬币,但不能将不同面值的硬币组合在一起。请返回可以用这些硬币构成的第k个最小金额。1<=coins.length<=15。1<=coins[i]<=2......
  • 2024-2025-1 20241329 《计算机基础与程序设计》第十周学习总结
    作业信息作业归属课程:2024-2025-1-计算机基础与程序设计作业要求:2024-2025-1计算机基础与程序设计第十周作业作业目标:信息系统、数据库与SQL、人工智能与专家系统、人工神经网络、模拟与离散事件、排队系统、天气与地震模型、图形图像作业正文:2024-2025-120241329《计算机基......
  • [2024年3月10日]第15届蓝桥杯青少组stema选拔赛C++中高级(第二子卷、编程题(6))
    参考程序:#include<bits/stdc++.h>usingnamespacestd;intn;inta[305];intdp[305][305];//打掉ij之间所有靶子可以获得的最大积分(不含i,j)intmain(){cin>>n;for(inti=1;i<=n;i++){cin>>a[i];}a[0]=1;a[n+1]=1;for(inti=n......
  • 2024-2025-1 20241327 《计算机基础与程序设计》第十周学习总结
    作业信息|2024-2025-1-计算机基础与程序设计)||--|-|2024-2025-1计算机基础与程序设计第十周作业)||快速浏览一遍教材计算机科学概论(第七版),课本每章提出至少一个自己不懂的或最想解决的问题并在期末回答这些问题|作业正文|https://www.cnblogs.com/shr060414/p/18440575|教......
  • NOIp2024游记
    Day998244852打板子,发现不会板子。Day0开考,看t1,开始写,假掉了,急急急。然后重新想,继续写,还是过不了样例,急急急。。怎么感觉在写Div2D?1h过了t1,感觉要完蛋了。。开t2,怎么逝计数啊,稍微观察一下,怎么这么唐,10:00过了。开t3,不太会啊,如果枚举开始的边好像会重复很多啊。。......
  • 2024-2025-1 20241301 《计算机基础与程序设计》第十周学习总结
    |这个作业属于哪个课程|2024-2025-1-计算机基础与程序设计||这个作业要求在哪里|2024-2025-1计算机基础与程序设计第一周作业||这个作业的目标|<复习知识,巩固基础>||作业正文|https://www.cnblogs.com/HonJo/p/18580240|一、教材学习内容总结(一)字符串C语言中的字符串是一种......
  • 2024-2025-1 20241416 《计算机基础与程序设计》第十周学习总结
    这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计这个作业要求在哪里 <作业要求的链接>(https://www.cnblogs.com/rocedu/p/9577842.html#WEEK10)这个作业的目标 信息系统数据库与SQL人工智能与专家系统人工神经网络模拟与离散事件排队系统天气与地震模型图形图像......
  • ssm电动车租赁网站(10264)
     有需要的同学,源代码和配套文档领取,加文章最下方的名片哦一、项目演示项目演示视频二、资料介绍完整源代码(前后端源代码+SQL脚本)配套文档(LW+PPT+开题报告)远程调试控屏包运行三、技术介绍Java语言SSM框架SpringBoot框架Vue框架JSP页面Mysql数据库IDEA/Eclipse开发四、项......
  • 2024 年十大最佳网络安全风险管理工具,你用过哪个?
    网络安全风险管理是指组织识别、评估、监控和应对网络安全威胁和漏洞的系统性过程。它旨在帮助组织预测、预防和减轻网络攻击的潜在风险,从而保护信息资产、数据隐私以及网络基础设施。随着网络攻击的日益复杂,网络安全风险管理已成为现代企业不可或缺的一部分。网络安全风险......