hot100之双指针
移动0(283)
先看代码
class Solution {
public void moveZeroes(int[] nums) {
int idx0 = 0;
for (int idx = 0; idx < nums.length; idx++){
if(nums[idx] != 0){
int temp = nums[idx0];
nums[idx0] = nums[idx];
nums[idx] = temp;
idx0++;
}
}
}
}
- 分析
由于仅当 nums[idx] == 0 时 idx0和idx间距会扩大 即有idx0 ~idx 间都为0
idx0用于记录0的起始位置, idx 向前移动发现非0 填入idx0 idx0 向右移动
- 感悟
双指针通过停一动一, 将两次遍历融合在一次遍历中, 同时维护两个指针, 处理两个数据
盛最多水的容器(011)
先看代码
class Solution {
public int maxArea(int[] height) {
int res = 0;
int lef = 0;
int rig = height.length - 1;
while (lef < rig){
int area = (rig - lef) * Math.min(height[lef], height[rig]);
res = Math.max(res, area);
if (height[lef] < height[rig]){
lef++;
}else rig--;
}
return res;
}
}
- 分析
容器盛最多水由短板决定, 显然在相同短板下容器越宽越好 所以让左右板从最边缘开始
增大容器容量只能通过寻找更优最短板(lef++ OR rig--), 此时的 trade off 就是容器变窄
- 感悟
双指针技巧特别适合需要同时考虑多个值的处理场景
三数之和(015)
先看代码
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
int n = nums.length;
Arrays.sort(nums);
for (int i = 0; i < n; i++){
if (nums[i] > 0) break;
if (i > 0 && nums[i] == nums[i-1]) continue;
int lef = i+1;
int rig = n-1;
while (lef < rig){
int sum = nums[i] + nums[lef] + nums[rig];
if(sum == 0){
res.add(Arrays.asList(nums[i], nums[lef], nums[rig]));
while (lef < rig && nums[lef] == nums[lef+1]) lef++;
while (lef < rig && nums[rig] == nums[rig-1]) rig--;
lef++;
rig--;
}
else if(sum < 0) lef++;
else if(sum > 0) rig--;
}
}
return res;
}
}
- 分析
分解问题成定一找二 寻找 nums[i] + nums[j] = - nums[k] 且 k < i, j < n-1
nums[k] 要和 (nums[i] + nums[j]) 为异号, 且当 nums[k] > 0 时结束
k < i , j < n-1 可行性分析
因为 nums[i] + nums [j] + nums[k] i, j, k 可相互替换
k 枚举了所有 nums[i] OR nums[j] OR nums[k] < 0的情况
先通过 sort 对原数组排序 →(方便去重 | 便于 nums[k] > 0 时结束 )
- 感悟
写完了两数之和, 第一感觉是要以nums[k]作target , 取nums[i] + nums[j]作两数之和
但分析之后发现 还是用了二分
时间复杂度: 双指针O(n*logn + n²/2 ), hash O(n² + k(n))
双指针有 n²/2 因为只枚举小于0情况, 由实际动态浮动 , 这里就先取个2
k(n)指哈希计算、解决哈希冲突, 及哈希扩容
空间复杂度: 双指针O(1), hash O(n² → 利用hashset去重) 双指针在res中操作, 而hash 还要维护set
另外, hash代码实现比较麻烦 orz
接雨水(042)
先看代码
class Solution {
public int trap(int[] height) {
int res = 0;
int lef = 0;
int rig = height.length-1;
int preMax = 0;
int sufMax = 0;
while (lef < rig){
preMax = Math.max(preMax, height[lef]);
sufMax = Math.max(sufMax, height[rig]);
res += preMax > sufMax ? sufMax - height[rig--] : preMax - height[lef++];
}
return res;
}
}
- 分析
通过维护全局两侧最高板, 采用了盛最多水的容器(011)的做法 寻找最优短板
对遍历到的块的接水量进行计算
- 感悟
暂无
hot100之双指针的更多相关文章
- [LeetCode] #167# Two Sum II : 数组/二分查找/双指针
一. 题目 1. Two Sum II Given an array of integers that is already sorted in ascending order, find two n ...
- [LeetCode] #1# Two Sum : 数组/哈希表/二分查找/双指针
一. 题目 1. Two SumTotal Accepted: 241484 Total Submissions: 1005339 Difficulty: Easy Given an array of ...
- Leetcode解题思想总结篇:双指针
Leetcode解题思想总结篇:双指针 1概念 双指针:快慢指针. 快指针在每一步走的步长要比慢指针一步走的步长要多.快指针通常的步速是慢指针的2倍. 在循环中的指针移动通常为: faster = f ...
- Longest Substring Without Repeating Characters - 哈希与双指针
题意很简单,就是寻找一个字符串中连续的最长包含不同字母的子串. 其实用最朴素的方法,从当前字符开始寻找,找到以当前字符开头的最长子串.这个方法猛一看是个n方的算法,但是要注意到由于字符数目的限制,其实 ...
- leetcode 15. 3Sum 双指针
题目链接 给n个数, 找出三个数相加结果为0的所有的组, 不可重复. 用双指针的思想,O(n^2)暴力的找, 注意判重复. class Solution { public: vector<vec ...
- hdu_5806_NanoApe Loves Sequence Ⅱ(双指针)
题目链接:hdu_5806_NanoApe Loves Sequence Ⅱ 题意: 给你一段数,问你有多少个区间满足第K大的数不小于m 题解: 直接双指针加一下区间就行 #include<cs ...
- BZOJ_2679_[Usaco2012 Open]Balanced Cow Subsets _meet in middle+双指针
BZOJ_2679_[Usaco2012 Open]Balanced Cow Subsets _meet in middle+双指针 Description Farmer John's owns N ...
- BZOJ_3048_[Usaco2013 Jan]Cow Lineup _双指针
BZOJ_3048_[Usaco2013 Jan]Cow Lineup _双指针 Description Farmer John's N cows (1 <= N <= 100,000) ...
- BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针
BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间, ...
- (双指针 二分) leetcode 167. Two Sum II - Input array is sorted
Given an array of integers that is already sorted in ascending order, find two numbers such that the ...
随机推荐
- JDK各个版本发布时间和版本名称
版权 版本 名称 发行日期 JDK 1.0 Oak(橡树) 1996-01-23 JDK 1.1 1997-02-19 JDK 1.1.4 Sparkler(宝石) 1997-09-12 JDK ...
- 2025年3月GESP八级真题解析
第一题--上学 题目描述 C 城可以视为由 \(n\) 个结点与 \(m\) 条边组成的无向图.这些结点依次以 \(1,2,-,n\) 标号,边依次以 \(1,2,-,m\) 标号.第 \(i\) 条 ...
- 如何让tcxGrid左边显示序号
第一步: 设置cxgrid的属性, OptionsView.Indicator = True 第二步: 写OnCustomDrawIndicatorCell方法 procedure TForm1.cx ...
- unigui的错误delphi clientHeight:property clientheight does not exist【10】
在unigui运行中发现这样的错误clientHeight:property clientheight does not exist. 这是啥原因.从老版本中复制过来的代码含dfm会出现这样的错误. ...
- Java 中的 young GC、old GC、full GC 和 mixed GC 的区别是什么?
Java 中的 young GC.old GC.full GC 和 mixed GC 的区别 在 Java 中,垃圾回收(GC)可以分为几种不同类型,包括 young GC.old GC.full G ...
- excel使用VBA连接access
需要的引用: 下面的代码涉及excel对access数据库的增删改查,可以按照需要查找使用 1 '远程链接模块 2 Option Explicit 3 Dim con As New ADODB.Con ...
- DDD领域驱动大纲讲义
DDD领域驱动模型 什么是领域?什么是领域模型? 没有丰富的领域知识能做出复杂的银行业业务软件吗 ? 没门 . 答案永远是否定的 . 那么谁 了解银行业业务 ? 软件架构师吗 ? 不 , 他只是在使用 ...
- EFCore 实体追踪
理解: EFCore通过一种机制实时追踪实体的属性是否有改变的一种机制,比如下方代码 通过EFCore查出来的数据List集合里的实体,在item.Manager = "菲菲";属 ...
- 基于Python和uiautomation的Windows桌面自动化操作方案
基于Python和uiautomation的Windows桌面自动化操作方案 在日常开发和测试过程中,我们经常需要对Windows桌面应用程序进行自动化操作.本文将记录如何使用uiautomation ...
- 【代码】Android|获取存储权限并创建、存储文件
版本:Android 11及以上,gradle 7.0以上,Android SDK > 29 获取存储权限 获取存储权限参考:Android 11 外部存储权限适配指南及方案,这篇文章直接翻到最 ...