class050 双指针技巧与相关题目【算法】

news2025/1/4 19:18:34

class050 双指针技巧与相关题目【算法】

算法讲解050【必备】双指针技巧与相关题目
在这里插入图片描述

code1 922. 按奇偶排序数组 II

// 按奇偶排序数组II
// 给定一个非负整数数组 nums。nums 中一半整数是奇数 ,一半整数是偶数
// 对数组进行排序,以便当 nums[i] 为奇数时,i也是奇数
// 当 nums[i] 为偶数时, i 也是 偶数
// 你可以返回 任何满足上述条件的数组作为答案
// 测试链接 : https://leetcode.cn/problems/sort-array-by-parity-ii/

奇数指针,偶数指针

package class050;

// 按奇偶排序数组II
// 给定一个非负整数数组 nums。nums 中一半整数是奇数 ,一半整数是偶数
// 对数组进行排序,以便当 nums[i] 为奇数时,i也是奇数
// 当 nums[i] 为偶数时, i 也是 偶数
// 你可以返回 任何满足上述条件的数组作为答案
// 测试链接 : https://leetcode.cn/problems/sort-array-by-parity-ii/
public class Code01_SortArrayByParityII {

	// 时间复杂度O(n),额外空间复杂度O(1)
	public static int[] sortArrayByParityII(int[] nums) {
		int n = nums.length;
		for (int odd = 1, even = 0; odd < n && even < n;) {
			if ((nums[n - 1] & 1) == 1) {
				swap(nums, odd, n - 1);
				odd += 2;
			} else {
				swap(nums, even, n - 1);
				even += 2;
			}
		}
		return nums;
	}

	public static void swap(int[] nums, int i, int j) {
		int tmp = nums[i];
		nums[i] = nums[j];
		nums[j] = tmp;
	}

}

code2 287. 寻找重复数

// 寻找重复数
// 给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n)
// 可知至少存在一个重复的整数。
// 假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。
// 你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。
// 测试链接 : https://leetcode.cn/problems/find-the-duplicate-number/

快指针 慢指针
链表找第一个入环结点

package class050;

// 寻找重复数
// 给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n)
// 可知至少存在一个重复的整数。
// 假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。
// 你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。
// 测试链接 : https://leetcode.cn/problems/find-the-duplicate-number/
public class Code02_FindTheDuplicateNumber {

	// 时间复杂度O(n),额外空间复杂度O(1)
	public static int findDuplicate(int[] nums) {
		if (nums == null || nums.length < 2) {
			return -1;
		}
		int slow = nums[0];
		int fast = nums[nums[0]];
		while (slow != fast) {
			slow = nums[slow];
			fast = nums[nums[fast]];
		}
		// 相遇了,快指针回开头
		fast = 0;
		while (slow != fast) {
			fast = nums[fast];
			slow = nums[slow];
		}
		return slow;
	}

}

code3 42. 接雨水

// 接雨水
// 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水
// 测试链接 : https://leetcode.cn/problems/trapping-rain-water/

求i位置:max(min(左侧最大值和右侧最大值)-i位置的高度,0)

package class050;

// 接雨水
// 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水
// 测试链接 : https://leetcode.cn/problems/trapping-rain-water/
public class Code03_TrappingRainWater {

	// 辅助数组的解法(不是最优解)
	// 时间复杂度O(n),额外空间复杂度O(n)
	// 提交时改名为trap
	public static int trap1(int[] nums) {
		int n = nums.length;
		int[] lmax = new int[n];
		int[] rmax = new int[n];
		lmax[0] = nums[0];
		// 0~i范围上的最大值,记录在lmax[i]
		for (int i = 1; i < n; i++) {
			lmax[i] = Math.max(lmax[i - 1], nums[i]);
		}
		rmax[n - 1] = nums[n - 1];
		// i~n-1范围上的最大值,记录在rmax[i]
		for (int i = n - 2; i >= 0; i--) {
			rmax[i] = Math.max(rmax[i + 1], nums[i]);
		}
		int ans = 0;
		//   x              x
		//   0 1 2 3...n-2 n-1
		for (int i = 1; i < n - 1; i++) {
			ans += Math.max(0, Math.min(lmax[i - 1], rmax[i + 1]) - nums[i]);
		}
		return ans;
	}

	// 双指针的解法(最优解)
	// 时间复杂度O(n),额外空间复杂度O(1)
	// 提交时改名为trap
	public static int trap2(int[] nums) {
		int l = 1, r = nums.length - 2, lmax = nums[0], rmax = nums[nums.length - 1];
		int ans = 0;
		while (l <= r) {
			if (lmax <= rmax) {
				ans += Math.max(0, lmax - nums[l]);
				lmax = Math.max(lmax, nums[l++]);
			} else {
				ans += Math.max(0, rmax - nums[r]);
				rmax = Math.max(rmax, nums[r--]);
			}
		}
		return ans;
	}

}

code4 881. 救生艇

// 救生艇
// 给定数组 people
// people[i]表示第 i 个人的体重 ,船的数量不限,每艘船可以承载的最大重量为 limit
// 每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit
// 返回 承载所有人所需的最小船数
// 测试链接 : https://leetcode.cn/problems/boats-to-save-people/

双指针
数组从小到大排序
体重小和体重大一船,或者体重大一船

拓展:两个人体重和只能是偶数才能一船
可以分为奇数数组偶数数组,分别求出再相加

package class050;

import java.util.Arrays;

// 救生艇
// 给定数组 people
// people[i]表示第 i 个人的体重 ,船的数量不限,每艘船可以承载的最大重量为 limit
// 每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit
// 返回 承载所有人所需的最小船数
// 测试链接 : https://leetcode.cn/problems/boats-to-save-people/
public class Code04_BoatsToSavePeople {

	// 时间复杂度O(n * logn),因为有排序,额外空间复杂度O(1)
	public static int numRescueBoats(int[] people, int limit) {
		Arrays.sort(people);
		int ans = 0;
		int l = 0;
		int r = people.length - 1;
		int sum = 0;
		while (l <= r) {
			sum = l == r ? people[l] : people[l] + people[r];
			if (sum > limit) {
				r--;
			} else {
				l++;
				r--;
			}
			ans++;
		}
		return ans;
	}

}

code5 11. 盛最多水的容器

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

双指针l,r
当前height[l]小,l++
否则r–

package class050;

// 盛最多水的容器
// 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
// 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水
// 返回容器可以储存的最大水量
// 说明:你不能倾斜容器
// 测试链接 : https://leetcode.cn/problems/container-with-most-water/
public class Code05_ContainerWithMostWater {

	// 时间复杂度O(n),额外空间复杂度O(1)
	public static int maxArea(int[] height) {
		int ans = 0;
		for (int l = 0, r = height.length - 1; l < r;) {
			ans = Math.max(ans, Math.min(height[l], height[r]) * (r - l));
			if (height[l] <= height[r]) {
				l++;
			} else {
				r--;
			}
		}
		return ans;
	}

}

code6 code6 475. 供暖器

// 供暖器
// 冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。
// 在加热器的加热半径范围内的每个房屋都可以获得供暖。
// 现在,给出位于一条水平线上的房屋 houses 和供暖器 heaters 的位置
// 请你找出并返回可以覆盖所有房屋的最小加热半径。
// 说明:所有供暖器都遵循你的半径标准,加热的半径也一样。
// 测试链接 : https://leetcode.cn/problems/heaters/

双指针i,j
对于每一个房屋[i]找到最优的供暖器[j],最优半径

package class050;

import java.util.Arrays;

// 供暖器
// 冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。
// 在加热器的加热半径范围内的每个房屋都可以获得供暖。
// 现在,给出位于一条水平线上的房屋 houses 和供暖器 heaters 的位置
// 请你找出并返回可以覆盖所有房屋的最小加热半径。
// 说明:所有供暖器都遵循你的半径标准,加热的半径也一样。
// 测试链接 : https://leetcode.cn/problems/heaters/
public class Code06_Heaters {

	// 时间复杂度O(n * logn),因为有排序,额外空间复杂度O(1)
	public static int findRadius(int[] houses, int[] heaters) {
		Arrays.sort(houses);
		Arrays.sort(heaters);
		int ans = 0;
		for (int i = 0, j = 0; i < houses.length; i++) {
			// i号房屋
			// j号供暖器
			while (!best(houses, heaters, i, j)) {
				j++;
			}
			ans = Math.max(ans, Math.abs(heaters[j] - houses[i]));
		}
		return ans;
	}

	// 这个函数含义:
	// 当前的地点houses[i]由heaters[j]来供暖是最优的吗?
	// 当前的地点houses[i]由heaters[j]来供暖,产生的半径是a
	// 当前的地点houses[i]由heaters[j + 1]来供暖,产生的半径是b
	// 如果a < b, 说明是最优,供暖不应该跳下一个位置
	// 如果a >= b, 说明不是最优,应该跳下一个位置
	public static boolean best(int[] houses, int[] heaters, int i, int j) {
		return j == heaters.length - 1 
				||
			   Math.abs(heaters[j] - houses[i]) < Math.abs(heaters[j + 1] - houses[i]);
	}

}

code7 41. 缺失的第一个正数

// 缺失的第一个正数
// 给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
// 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。
// 测试链接 : https://leetcode.cn/problems/first-missing-positive/

双指针
l:表示l左侧的位置上放好l+1的值
r:垃圾区;最好预期1…r的值都有
①nums[l]=l+1,l++
②nums[l]<=l,垃圾
③nums[l]>r,垃圾
④nums[nums[l]-1]=nums[l],重复垃圾
⑤交换(l,nums[l]-1)
返回l+1

package class050;

// 缺失的第一个正数
// 给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
// 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。
// 测试链接 : https://leetcode.cn/problems/first-missing-positive/
public class Code07_FirstMissingPositive {

	// 时间复杂度O(n),额外空间复杂度O(1)
	public static int firstMissingPositive(int[] arr) {
		// l的左边,都是做到i位置上放着i+1的区域
		// 永远盯着l位置的数字看,看能不能扩充(l++)
		int l = 0;
		// [r....]垃圾区
		// 最好的状况下,认为1~r是可以收集全的,每个数字收集1个,不能有垃圾
		// 有垃圾呢?预期就会变差(r--)
		int r = arr.length;
		while (l < r) {
			if (arr[l] == l + 1) {
				l++;
			} else if (arr[l] <= l || arr[l] > r || arr[arr[l] - 1] == arr[l]) {
				swap(arr, l, --r);
			} else {
				swap(arr, l, arr[l] - 1);
			}
		}
		return l + 1;
	}

	public static void swap(int[] arr, int i, int j) {
		int tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
	}

}

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

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

相关文章

springboot项目中注入bean后,调用时报n

需求&#xff1a; 在socket接收到上报数据后&#xff0c;在handler中调用工具类中ProtocolAnalyse的conAnalyse(byte[] data, int dataLen)解析数据。解析数据后&#xff0c;将解析后的结果保存至数据库。注入了三个bean&#xff1a; Autowiredprivate PersonTeService person…

8个Python高效数据分析的技巧!

一行代码定义List 定义某种列表时&#xff0c;写For 循环过于麻烦&#xff0c;幸运的是&#xff0c;Python有一种内置的方法可以在一行代码中解决这个问题。下面是使用For循环创建列表和用一行代码创建列表的对比。 x [1,2,3,4] out [] for item in x:out.append(item**2) …

通付盾连续九年荣登《中国网络安全企业100强》榜单,再次彰显创新与实力!

2023年12月1日&#xff0c;由中国计算机学会抗恶劣环境计算机专业委员会、信息产业信息安全测评中心、安全牛联合发起的第十一版《中国网络安全企业100强》正式发布。通付盾凭借强大的创新技术和优质的服务能力&#xff0c;再度入选百强榜单。此为自2015年起&#xff0c;通付盾…

YOLOv5改进: RT-DETR引入YOLOv5,neck和检测头助力检测

💡💡💡本文独家改进: 1) RT-DETR neck代替YOLOv5 neck部分; 2)引入RTDETRDecoder 多个订阅者要求(多个订阅者有需求会在专栏里进行更新),想出一期RT-DETR的neck引入到YOLOv5,那就安排 💡💡💡Yolov5/Yolov7魔术师,独家首发创新(原创),适用于Yolov5、Yo…

C++ 操作MinIO做文件数据的上传和下载(踩坑与经验)包含编译包

前言 最近在做项目流程优化&#xff0c;准备将之前的java对文件的操作转换到c端&#xff0c;因此做了基于c的minio操作的测试demo。期间的各种踩坑与问题&#xff0c;花了一天时间总算是成功了&#xff0c;当然还有一些小问题&#xff0c;等待后续其他大拿解决。 项目环境 v…

【Android】Glide的简单使用(上)

文章目录 引入Glide的优点:缺点: 使用常用方法:从网络加载图片从文件加载图片加载resource资源加载URI地址设置占位图出错时的图片占位图图片过渡的Transitions自定义过渡动画图片大小调整缩放图片播放gifasGif()把Gif当作Bitmap播放显示本地视频缩略图 引入 Glide是Google员工…

ISNAS-DIP: Image-Specific Neural Architecture Search for Deep Image Prior

ISNAS-DIP&#xff1a;用于深度图像先验的图像特定神经架构搜索 论文链接&#xff1a;https://arxiv.org/abs/2111.15362v2 项目链接&#xff1a;https://github.com/ozgurkara99/ISNAS-DIP Abstract 最近的研究表明&#xff0c;卷积神经网络(CNN)架构在频谱上偏向较低频率&…

装修风格及要求

水电改造 报价&#xff1f; 电线 3C认证国标BV线&#xff08;非BVR&#xff09;&#xff0c;电线上有厂名&#xff0c;买足百米的 厨卫空调4平方线普通插座2.5平方线冰箱2.5平方线照明2.5平方线入户主线6平方或10平方 地面电线点对点&#xff0c;线和线管连接处要有锁扣 品…

Pandas使用过程中的神器加持 你不用不要怪我

Pandas是我们日常处理表格数据最常用的包&#xff0c;但是对于数据分析来说&#xff0c;Pandas的DataFrame还不够直观&#xff0c;所以今天我们将介绍4个和Pandas相关的Python包&#xff0c;可以将Pandas的DataFrame转换交互式表格&#xff0c;让我们可以直接在上面进行数据分析…

将文件夹中所有文件名取出

dir C:\Users\是啊\Desktop\实验五/b>C:\Users\是啊\Desktop\1111.xls C:\Users\是啊\Desktop\实验五&#xff08;这个是文件夹路径&#xff09; /b &#xff08;参数&#xff09; C:\Users\是啊\Desktop\1111.xls&#xff08;文件名输出的文件路径&#xff09;

电路装修干货上篇|装修小白硬装必做功课。福州中宅装饰,福州装修

你是否曾经遇到过这样的情况&#xff1a;同时开启浴霸和电磁炉时&#xff0c;家里的电闸却跳了。这种情况往往会让人们对家居装修中的电线布置产生疑问。今天&#xff0c;以一位从业装修工作10年的工长的经验&#xff0c;为大家解答有关电线布置的常见问题。 1️⃣电线的平方数…

★581. 最短无序连续子数组

581. 最短无序连续子数组 方法一&#xff1a; class Solution {public int findUnsortedSubarray(int[] nums) {// 数组的复制int[] sortednums new int[nums.length];System.arraycopy(nums, 0, sortednums, 0, nums.length);Arrays.sort(sortednums);int l0,rnums.length-1;…

基于Java SSM框架实现汽车在线销售系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现汽车在线销售系统演示 摘要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&a…

Leetcode—383.赎金信【简单】

2023每日刷题&#xff08;五十&#xff09; Leetcode—383.赎金信 实现代码 class Solution { public:int arr[26] {0};int arr2[26] {0};bool canConstruct(string ransomNote, string magazine) {int len ransomNote.size();int len2 magazine.size();for(int i 0; i …

前置微小信号放大器在传感器测试中的应用

前置微小信号放大器在医疗领域中有广泛的应用。它们是一种专门设计用于放大微弱信号的放大器&#xff0c;可以提升信号的强度和质量&#xff0c;从而帮助医生进行准确的诊断和治疗。以下是前置微小信号放大器在医疗中的几个主要应用。 前置微小信号放大器常用于心电图设备中。E…

开始使用高性能、低延迟的对象存储服务 Amazon S3 Express One Zone

全新的对象存储服务 Amazon S3 Express One Zone 旨在提供比 Amazon S3 Standard 高出10倍的性能&#xff0c;同时每秒可处理数十万个请求&#xff0c;并且延迟始终保持在个位数毫秒级&#xff0c;因此非常适合存储最常访问的数据和要求最苛刻的应用程序。将对象存储和复制到单…

21款奔驰GLC300L升级HUD抬头显示 平视仪表信息

说起HUD抬头显示这个配置&#xff0c;最初是用在战斗机上的&#xff0c;它可以让战斗机驾驶员读取飞机的各种信息和状态&#xff0c;而无需移动头部&#xff0c;这样就能够有效的提高效率。但随着汽车技术的进步HUD这种配置也逐渐下放到民用车上。 发展到今&#xff0c;车上的…

Linux Shell 基础命令

Linux 是一个开源的操作系统&#xff0c;其命令行界面是它的重要组成部分。在这个界面下&#xff0c;Shell 是一个能够与操作系统进行交互的工具。Shell 是一种程序&#xff0c;它能够接收用户输入的命令&#xff0c;并将这些命令发送到操作系统中进行处理。 在 Linux 中&…

UE小:UE5性能分析

开始录制性能追踪 要开始录制性能追踪&#xff0c;您可以简单地点击界面上的“开始录制”按钮。 查看追踪数据 录制完成后&#xff0c;点击“Trace”菜单中的“UnrealInsights”选项来查看追踪数据。 使用命令行进行追踪 如果点击录制按钮没有反应&#xff0c;您可以通过命令…

R语言【rgbif】——最全最详细的函数解读(name_suggest)

name_suggest最全最详细的参数解读 1. name_suggest的基本情况2. name_suggest的参数3. name_suggest的示例与理解3.1 参数 【q】3.2 参数【rank】3.3 参数【limit】3.4 参数【fields】3.5 参数【datasetKey】3.6 参数【curlopts】 1. name_suggest的基本情况 name_suggest是用…