当前位置: 首页 > article >正文

【力扣Hot100】双指针

全部来自力扣hot 100

移动零:两个指针一前一后,一起从前往后遍历

盛水最多的容器:两个指针一个从前往后,一个从后往前

三数之和:两个指针一个从前往后,一个从后往前。

双指针问题思考步骤要从简单的双重循环开始优化,找规律,看到了某一步骤是不是就能省略后面的步骤。可以从:两个一起从前往后,一个从前往后、一个从后往前,两种情况来考虑是否可以优化

当然我是想不出来的>.<

1. 移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:

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

示例 2:

输入: nums =[0]输出:[0]

提示:

  • 1 <= nums.length <= 104
  • 231 <= nums[i] <= 231 - 1

题解:

设置一个快指针一个慢指针,维护快慢指针中间全是0,慢指针指向非零的最后一位,快指针从头到尾全部遍历。当慢指针遇到零的时候,交换快慢指针。

如果数组没有0,那么快慢指针始终指向同一个位置,每个位置自己和自己交换;如果数组有0,快指针先走一步,此时慢指针对应的就是0,所以要交换。

2. 盛水最多的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

**说明:**你不能倾斜容器。

示例 1:

!https://aliyun-lc-upload.oss-cn-hangzhou.aliyuncs.com/aliyun-lc-upload/uploads/2018/07/25/question_11.jpg

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

示例 2:

输入:height = [1,1]
输出:1

提示:

  • n == height.length
  • 2 <= n <= 105
  • 0 <= height[i] <= 104

题解

左指针从最左边开始,右指针从最右边开始,每次两个中高度最低的那个向里面移动一位,直到指针相遇。

class Solution {
public:
    int maxArea(vector<int>& height) {
        int l = 0, r = height.size() - 1;
        int ans = (r - l) * min(height[l], height[r]);
        while(l < r) {
            if(height[l] < height[r]) {
                l ++;
            } else {
                r --;
            }
            ans = max(ans, (r - l) * min(height[l], height[r]));
        }
        return ans;
    }
};

3. 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

**注意:**答案中不可以包含重复的三元组。

示例 1:

输入: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] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

提示:

  • 3 <= nums.length <= 3000
  • 105 <= nums[i] <= 105

题解

不重复→数组先排序一下

first从前往后遍历,对于每一个first,我们需要找出nums[second] + nums[third] == -nums[first]

A + B = C,就是前面的A + B问题。

我们使用双指针来解决。设置左右两个指针,second从 first-1 开始从前往后遍历,third从 n - 1 开始从后往前遍历。

每一个second对应一个third。

如果nums[second] + nums[third] > -nums[first], 那么该second对应的third应该更小,所以third —;

对于前后两个second1,second2,如果nums[second1] + nums[third] > need,那么nums[second2] + nums[third] 也会 > need;

所以,third是从后往前一直遍历,不需要回去。

这样,当second和third相遇的时候,就可以break。

需要注意细节:nums[first] == nums[first - 1]的时候,应该跳过;nums[second] == nums[second - 1]的时候,也应该跳过。这样就能避免同一个值取两次。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> ans;

        int n = nums.size();
        for(int first = 0; first <= n - 3; first ++ ) {
            if(first != 0 && nums[first] == nums[first - 1]) continue;
            int third = n - 1;
            int need = -nums[first];
            for(int second = first + 1; second < third; second ++ ) {
                if(second != first + 1 && nums[second] == nums[second - 1]) continue;
                while(second < third && nums[second] + nums[third] > need) third --;
                if(second == third) break;
                if(nums[second] + nums[third] == need) ans.push_back({nums[first], nums[second], nums[third]});
            }
        }
        return ans;
    }
};

http://www.kler.cn/a/504929.html

相关文章:

  • 【AIGC】SYNCAMMASTER:多视角多像机的视频生成
  • iOS - 关联对象的实现
  • c语言 --- 字符串
  • 2025宝塔API一键建站系统PHP源码
  • 浅谈云计算12 | KVM虚拟化技术
  • 基于python的网页表格数据下载--转excel
  • Linux磁盘存储与内存管理命令
  • 【C++学习篇】红黑树 从入门到进阶
  • Vue 开发者的 React 实战指南:表单处理篇
  • 微信小程序:跨页面数据修改全攻略
  • Web前端------HTML块级和行内标签之行内标签
  • Inxpect毫米波安全雷达:精准检测与动态保护,工业自动化可靠选择
  • 求 n 个数的最小公倍数(详解版)
  • Go语言编译的exe文件占用内存过大解决办法
  • HTTP中form-data、x-www-form-urlencoded、raw、binary的区别
  • L4-Prompt-Delta
  • 【零基础入门unity游戏开发——unity3D篇】URP 3D光源组件(Light)介绍、烘培灯光、实现太阳耀斑镜头光晕效果(基于unity6开发介绍)
  • 高等数学学习笔记 ☞ 不定积分与积分公式
  • JavaScript this、回调函数、事件流
  • 电脑电源灯一闪一闪开不了机 原因分析
  • 确保使用爬虫技术时的合法性
  • MAC上安装Octave
  • Kotlin实现DataBinding结合ViewModel的时候,提示找不到Unresolved reference: BR解决方案
  • [完整指南]如何轻松备份锁定/禁用的iPhone?
  • Mysql--实战篇--SQL优化(查询优化器,常用的SQL优化方法,执行计划EXPLAIN,Mysql性能调优,慢日志开启和分析等)
  • 【大厂面试AI算法题中的知识点】方向涉及:ML/DL/CV/NLP/大数据...本篇介绍为什么self-attention可以堆叠多层,这有什么作用?