LeetCode HOT100(二)双指针

移动0

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。

输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]


解法1:双指针+交换
指针L:维护一个非零序列,L之前的元素都是非零的元素
指针R:寻找非零的元素,将其加入到L维护的序列中

public void moveZeroes(int[] nums) {int l = 0;int r = 0;while(r<nums.length){if(nums[r]!=0)swap(nums,l++,r);r++;}
}public void swap(int[] nums,int l,int r){if(l == r) return;nums[l] = nums[l] ^ nums[r];nums[r] = nums[l] ^ nums[r];nums[l] = nums[l] ^ nums[r];
}
func moveZeroes(nums []int)  {slow := 0for i,_ := range nums{if nums[i]!=0{tmp := nums[slow]nums[slow] = nums[i]nums[i] = tmpslow++}}
}

解法2:双指针+赋值0
解法和1类似,只不过1是交换非零元素和0元素,2将非零元素全部移动到前面,后面统一赋值为0

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

盛水最多的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
image.png

输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。


解放1:双指针
在这里插入图片描述

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

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

因此,初始化双指针分列水槽左右两端,循环每轮将短板向内移动一格,并更新面积最大值,直到两指针相遇时跳出;即可获得最大面积。

public int maxArea(int[] height) {int l = 0;int r = height.length-1;int area = 0;while(l<r){if(height[l]<height[r]){int cur = height[l]*(r-l);area = Math.max(area, cur);l++;}else{int cur = height[r]*(r-l);area = Math.max(area, cur);r--;}}return area;
}
func maxArea(height []int) int {l,r := 0,len(height)-1res := 0for l<r {if height[l] < height[r]{res = int(math.Max(float64(res),float64(height[l]*(r-l))))l++;}else{res = int(math.Max(float64(res),float64(height[r]*(r-l))))r--;}}return res
}

三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。


解法1:排序+双指针
先排序保证数据有序,这样就不会保存重复的数组了
接下来,外层循环确定一个 i 的值,内层循环使用左右两端向中间移动的双指针

//每个指针移动时跳过重复元素版,力扣不友好,时间还不如不跳过的快
public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> res = new ArrayList<>();Arrays.sort(nums);int i=0; while(i<nums.length-2){int sum = -nums[i];int j=i+1; int k=nums.length-1;while(j<k){int cur = nums[j]+nums[k];if(cur > sum){while( j<k && nums[k]==nums[k-1])k--;k--;}else if(cur < sum){while( j<k && nums[j]==nums[j+1])j++;j++;}else{List<Integer> tmp = new ArrayList<>();tmp.add(nums[i]);tmp.add(nums[j]);tmp.add(nums[k]);res.add(tmp);while( j<k && nums[k]==nums[k-1])k--;k--;while( j<k && nums[j]==nums[j+1])j++;j++;}}while(i<nums.length-2 && nums[i+1]==nums[i])i++;i++;}return res;
}//不跳过版
public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> res = new ArrayList<>();Arrays.sort(nums);int i=0; while(i<nums.length-2){int sum = -nums[i];int j=i+1; int k=nums.length-1;while(j<k){int cur = nums[j]+nums[k];if(cur > sum)k--;else if(cur < sum)j++;else{List<Integer> tmp = new ArrayList<>();tmp.add(nums[i]);tmp.add(nums[j]);tmp.add(nums[k]);res.add(tmp);while(j<k&&nums[k]==nums[k-1])k--;k--;}}while(i<nums.length-2 && nums[i+1]==nums[i])i++;i++;}return res;
}
func threeSum(nums []int) [][]int {res := make([][]int,0)sort.Ints(nums)for i,v:=range nums{if i==len(nums)-2 {break}if i>0&&nums[i]==nums[i-1] {continue}target := -v;l,r := i+1,len(nums)-1for l<r {sum := nums[l]+nums[r]if sum>target{for l<r&&nums[r]==nums[r-1]{r--}r--;}else if sum<target{for l<r&&nums[l]==nums[l+1]{l++}l++}else{res = append(res,[]int{v,nums[l],nums[r]})for l<r&&nums[l]==nums[l+1]{l++}l++}}}return res
}

接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
在这里插入图片描述

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。


解法1:最大前缀+最大后缀
对于每一个柱子能接的水,取决于:

  1. 当前柱子高度h0
  2. 当前柱子左侧最高的柱子h1,当前柱子右侧最高的柱子h2,取二者最小的值
  3. 当前柱子能接的水为:min(h1,h2)-h0
public int trap(int[] height) {int len = height.length;int pre[] = new int[len];int suf[] = new int[len];pre[0] = height[0];for(int i=1; i<len; i++){pre[i] = Math.max(pre[i-1],height[i]);}suf[len-1] = height[len-1];for(int i=len-2; i>=0; i--){suf[i] = Math.max(suf[i+1],height[i]);}int sum = 0;for(int i=0; i<len; i++){int low = Math.min(pre[i],suf[i]);sum += (low-height[i]);}return sum;
}
func trap(height []int) int {if len(height)<3 {return 0}leng := len(height)leftMax := make([]int,leng)rightMax := make([]int,leng)leftMax[0] = height[0]for i:=1; i<len(height); i++ {if(leftMax[i-1]>height[i]){leftMax[i] = leftMax[i-1]}else{leftMax[i] = height[i]}}rightMax[len(height)-1] = height[len(height)-1]for i:=len(height)-2; i>=0; i-- {if rightMax[i+1]>height[i] {rightMax[i] = rightMax[i+1]}else{rightMax[i] = height[i]}}res := 0for i:=0; i<len(height); i++ {var curHeight intif(leftMax[i]>rightMax[i]){curHeight = rightMax[i]}else{curHeight = leftMax[i]}res+=(curHeight-height[i])}return res
}

解法2:双指针,解法1的节省空间的方法
解法1为了维持每个位置的左右边界最大值,使用数组来表示,可以使用双指针来代替数组。
每次双指针移动之后比较最大值,小的一方先移动。

public int trap(int[] height) {int len = height.length;int res = 0;int left = 0;int right = len-1;int leftMax = 0;int rightMax = 0;while(left<=right){leftMax = Math.max(leftMax,height[left]);rightMax = Math.max(rightMax,height[right]);if(leftMax<=rightMax){res+=(leftMax-height[left++]);}else{res+=(rightMax-height[right--]);}}return res;
}

解法3:单调栈
栈内元素依然是单调递减。
image.png
当遇到相等的时候也要出栈,但是在计算面积的时候,由于左右边界中有一条边界和当前计算的柱子高度相等,所以高度差是0,计算出来也没影响。

public int trap(int[] height) {int len = height.length;Deque<Integer> stack = new ArrayDeque<>();int res = 0;for(int i=0; i<len; i++){while(!stack.isEmpty() && height[stack.peek()]<=height[i]){int curIndex = stack.pop();if(stack.isEmpty()) break;int preIndex = stack.peek();res+=((i-1-preIndex)*(Math.min(height[preIndex],height[i])-height[curIndex]));}stack.push(i);}return res;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/43454.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“论基于构件的软件开发方法及其应用”写作框架,软考高级论文,系统架构设计师论文

论文真题 基于构作的软件开发 (Component-Based Software Development&#xff0c;CBSD) 是一种基于分布对象技术、强调通过可复用构件设计与构造软件系统的软件复用途径。基于构件的软件系统中的构件可以是COTS &#xff08;Commercial-Off-the-Shelf&#xff09;构件&#x…

Spring Boot轻松整合Minio实现文件上传下载功能

一、Linux 安装Minio 安装 在/root/xxkfz/soft目录下面创建文件minio文件夹&#xff0c;进入minio文件夹&#xff0c;并创建data目录&#xff1b; [rootxxkfz soft]# mkdir minio [rootxxkfz soft]# cd minio [rootxxkfz minio]# mkdir data 执行如下命令进行下载 [rootxx…

Java内存划分详解:从基础到进阶

Java内存划分详解&#xff1a;从基础到进阶 1. 程序计数器&#xff08;Program Counter Register&#xff09;2. Java虚拟机栈&#xff08;Java Virtual Machine Stack&#xff09;3. 堆&#xff08;Heap&#xff09;4. 方法区&#xff08;Method Area&#xff09;5. 运行时常量…

DDD架构面试问题

基础概念 什么是领域驱动设计&#xff08;DDD&#xff09;&#xff1f; 请解释一下DDD的核心思想和目标。 DDD中的领域&#xff08;Domain&#xff09;是什么&#xff1f; 请描述一下领域的概念以及它在软件开发中的重要性。 什么是限界上下文&#xff08;Bounded Context&am…

ArduPilot开源代码之OpticalFlow_backend

ArduPilot开源代码之OpticalFlow_backend 1. 源由2. Library设计3. 重要例程3.1 OpticalFlow_backend::_update_frontend3.2 OpticalFlow_backend::_applyYaw 4. 总结5. 参考资料 1. 源由 光流计是一种低成本定位传感器&#xff0c;所有的光流计设备传感驱动代码抽象公共部分统…

[计网初识1] TCP/UDP

学习内容 1.TCP建立链接的3次握手&#xff0c;断开连接的4次挥手 2.TCP报文段组成 内容 1.TCP 建立连接的3次握手? 假设主动方是客户端&#xff0c;被动方是服务端。 第一次 客户端给服务端发送 “hello,我是客户端” (TCP段中 SYN1) 第二次 服务端给客户端发送"我接…

从零开始的python学习生活2

接上封装 class Phone:__volt0.5def __keepsinglecore(self):print("让cpu以单核运行")def if5G(self):if self.__volt>1:print("5G通话已开启")else:self.__keepsinglecore()print("电量不足&#xff0c;无法使用5G通话&#xff0c;已经设置为单…

Django项目创建的准备工作【 2 】

【 一 】调整后端目录 #1 目录结构 """ ├── luffy_api├── logs/ # 项目运行时/开发时日志目录 - 包├── manage.py # 脚本文件├── luffy_api/ # 项目主应用&#xff0c;开发时的代码保存 - 包├── apps/ …

【Git基本操作】添加文件 | 修改文件 | 及其各场景下.git目录树的变化

目录 1. 添加文件&add操作和commit操作 2. .git树状目录的变化 3. git其他操作 4. 修改文件 4.1 git status 4.2 git diff 1. 添加文件&add操作和commit操作 add操作&#xff1a;将工作区中所有文件的修改内容 添加进版本库的暂存区中。commit操作&#xff1a;…

云端编码:将您的技术API文档安全存储在iCloud的最佳实践

云端编码&#xff1a;将您的技术API文档安全存储在iCloud的最佳实践 作为一名技术专业人士&#xff0c;管理不断增长的API文档库是一项挑战。iCloud提供了一个无缝的解决方案&#xff0c;允许您在所有设备上存储、同步和访问您的个人技术API文档。本文将指导您如何在iCloud中高…

系统服务综合实验(dns服务,nfs服务)

题目&#xff1a;现有主机 node01 和 node02&#xff0c;完成如下需求&#xff1a; 1、在 node01 主机上提供 DNS 和 WEB 服务 2、dns 服务提供本实验所有主机名解析 3、web服务提供 www.rhce.com 虚拟主机 4…

three-tile: 1. 第一个three-tile程序

上篇介绍了&#xff1a;three-tile&#xff1a; 一个开源的轻量级三维瓦片库-CSDN博客 three-tile 是一个开源的轻量级三维瓦片库&#xff0c;它基于threejs使用typescript开发&#xff0c;提供一个三维地形模型&#xff0c;能轻松给你的应用增加三维瓦片地图。 项目地址&…

C#知识|账号管理系统:UI层-添加账号窗体设计思路及流程。

哈喽,你好啊,我是雷工! 前边练习过详情页窗体的设计思路及流程: 《C#知识|上位机UI设计-详情窗体设计思路及流程(实例)》 本节练习添加账号窗体的UI设计,以下为学习笔记。 01 效果展示 02 添加窗体 在UI层添加Windows窗体,设置名称为:FrmAddAcount.cs 设置窗体属…

Nginx七层(应用层)反向代理:UWSGI代理uwsgi_pass篇

Nginx七层&#xff08;应用层&#xff09;反向代理 UWSGI代理uwsgi_pass篇 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this a…

数据结构模板2

Trie树&#xff1a;用来高效存储和查找字符串集合的数据结构&#xff1a; 模板题&#xff1a;https://www.acwing.com/problem/content/837/ AC代码&#xff1a; #include<bits/stdc.h> using namespace std; int son[100010][26],cnt[100010],idx; char str[100010]; …

数据的洞察力:SQL Server Analysis Services在数据分析中的卓越应用

数据的洞察力&#xff1a;SQL Server Analysis Services在数据分析中的卓越应用 在商业智能和数据分析领域&#xff0c;SQL Server Analysis Services (SSAS) 是一款强大的工具&#xff0c;它提供了多维数据和数据挖掘模型的创建、部署和管理功能。本文将深入探讨如何在SQL Se…

云端生活,智能管理:在iCloud中打造您的个人购物清单与预算计划

云端生活&#xff0c;智能管理&#xff1a;在iCloud中打造您的个人购物清单与预算计划 在快节奏的现代生活中&#xff0c;个人财务管理和购物规划变得尤为重要。iCloud提供了一个强大的平台&#xff0c;让我们能够存储、同步和共享个人购物清单与预算计划。本文将详细介绍如何…

代码随想录算法训练营第二十九天

452. 用最少数量的箭引爆气球 这道题目我原本的想法是只要当前的气球半径范围在已有的箭头能够击穿的气球半径内就可以实现 但是 箭射出去的地方是一个值 而不是一个范围 因此有相同的重叠范围的许多气球并一定都有相同的值&#xff0c;因此这种方法不可取 这题的主要局部最…

最短路径算法(算法篇)

算法之最短路径算法 最短路径算法 概念&#xff1a; 考查最短路径问题&#xff0c;可能会输入一个赋权图(也就是边带有权的图)&#xff0c;则一条路径的v1v2…vN的值就是对路径的边的权求和&#xff0c;这叫做赋权路径长&#xff0c;如果是无权路径长就是单纯的路径上的边数。…

mac安装配置cmake

本机是2015 macbook pro mid&#xff0c;已经有点老了&#xff0c;用homebrew下cmake老出问题 其实cmake官网安装也不麻烦 一、官网下载对应安装包 Download CMake 和所有dmg文件一样安装 二、改成命令行使用 一般来说 tutorial 给的都是命令行build 命令行的设置如下&am…