Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【优选算法】Pointer-Slice:双指针的算法切片(下)

【优选算法】Pointer-Slice:双指针的算法切片(下)

作者头像
DARLING Zero two
发布于 2024-12-26 00:39:15
发布于 2024-12-26 00:39:15
7300
代码可运行
举报
文章被收录于专栏:C语言C语言
运行总次数:0
代码可运行
本篇接上一篇双指针算法,继续处理剩下的经典题目

1.有效三角形的个数

✏️题目描述:

✏️示例:

传送门:有效三角形的个数

题解: 💻第一步:

一般针对三元的变量,优先想到的是三层 for 循环暴力枚举所有的组合,此时的时间复杂度为O(n³),明显是超时了。争取遍历一遍就能找出所有组合,那么就要减少无效的枚举

根据数学知识可知,假设三角形最大边为c,那么其余两边a、b之和大于c,就能确定一个三角形

为了减少无效的枚举,通常需要利用数列的单调性,就用sort函数迭代器对数组升序排序

💻第二步:

由于是三元,且依据数学知识,我们先固定其中一个数(从最大的开始)剩下两个数就可以利用双指针求组合

假设两数之和大于c,那么可以减小和,寻找是否还有符合要求的组合,即right--;假设两数之和小于c,那么需要增加和,寻找有符合要求的组合,即left++和相等时就返回组合,然后继续left++,因为减小和仍然有可能找到符合大于c的组合每判断一次和,就要执行一次移动,当left >= right就停止,此时最大数的组合情况已经全部找完,接下来c就减小一位,继续循环上述操作

注意c最多减小到索引为2的位置,保证依然为三元组合

💻代码实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Solution 
{
public:
    int triangleNumber(vector<int>& nums) 
    {
        sort(nums.begin(), nums.end());
        int ret = 0, n = nums.size();
        for (int i = n - 1; i >= 2; --i)
        {
            int left = 0, right = i - 1;
            while (left < right)
            {
                if (nums[left] + nums[right] > nums[i])
                {
                    ret += right - left;
                    right--;
                }
                else
                {
                    left++;
                }
            }
        }
        return ret;
    }
};

2.查找总价格为目标值的两个商品

✏️题目描述:

✏️示例:

传送门:查找总价格为目标值的两个商品

题解: 💻细节问题:

该题是上一题的简化版,显然是使用双指针找符合的组数

唯一不同的是上题要寻找所有符合的情况,该题找到一个符合的即可

💻代码实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <vector>
using namespace std;

class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target)
    {
        int left = 0, right = price.size() - 1;
        while (left < right)
        {
            int sum = price[left] + price[right];
            if (sum < target)
            {
                left++;
            }
            else if (sum > target)
            {
                right--;
            }
            else return { price[left], price[right] };
        }
        return{ -1,-1 };
    }
};

3.三数之和

✏️题目描述:

✏️示例:

传送门:三数之和

题解:

本题也是三元组合的问题,与有效三角形的个数那题的思路也是一样的,做到不漏情况是很简单的,但是本题要求不重复,那么这是本题要处理的难点,细节问题特别多

💻第一步: 不漏

或许可以通过暴力枚举+set容器去重,但仍然涉及时间复杂度高的问题,所以还是排序+双指针的方法减小时间复杂度

💻第二步: 不重

🚩left、right不重复

🚩固定的数不重复

因为此时其余两个数都是不变的,移动到下一个一样的数重复了之前的情况,为了减少不必要的枚举,当遇到重复的数时两种情况都需要跳过

💻细节问题:

注意不要在处理重复数的情况时移动越界,要考虑如果都是重复数的情况

💻代码实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Solution 
{
public:
    vector<vector<int>> threeSum(vector<int>& nums) 
    {
        sort(nums.begin(), nums.end());
        int n = nums.size();
        vector<vector<int>> ret;
        for (int i = 0; i < n; )
        {
            if (nums[i] > 0)
            {
                break;
            }
            int left = i + 1, right = n - 1, target = -nums[i];
            while (left < right)
            {
                int sum = nums[left] + nums[right];
                if (sum < target)
                {
                    left++;
                }
                else if(sum > target)
                {
                    right--;
                }
                else
                {
                    ret.push_back({ nums[i],nums[left],nums[right] });
                    left++, right--;
                    while (left < right && nums[left] == nums[left - 1])
                    {
                        left++;
                    }
                    while (left < right && nums[right] == nums[right + 1])
                    {
                        right--;
                    }
                }
            }
            i++;
            while (i < n && nums[i] == nums[i - 1])
            {
                i++;
            }
        }
        return ret;
    }
};

4.四数之和

✏️题目描述:

✏️示例:

传送门:四数之和

💻细节问题:

四数之和三数之和是一个思路,只不过是要固定两个数套用两层 for 循环处理两次边界问题,注意双指针运算过程中,比较的值可能会太大,所以要用 long long

💻代码实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Solution
{
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target)
    {
        sort(nums.begin(), nums.end());
        int n = nums.size();
        vector<vector<int>> ret;
        for (int i = 0; i < n; )
        {
            for (int j = i + 1; j < n; )
            {
                int left = j + 1, right = n - 1;
                long long aim = (long long)target - nums[i] - nums[j];
                while (left < right)
                {
                    int sum = nums[left] + nums[right];
                    if (sum < aim)
                    {
                        left++;
                    }
                    else if (sum > aim)
                    {
                        right--;
                    }
                    else
                    {
                        ret.push_back({ nums[i],nums[j],nums[left],nums[right] });
                        left++,right--;
                        while (left < right && nums[left] == nums[left - 1])
                        {
                            left++;
                        }
                        while (left < right && nums[right] == nums[right + 1])
                        {
                            right--;
                        }
                    }
                }
                j++;
                while (j < n && nums[j] == nums[j - 1])
                {
                    j++;
                }
            }
            i++;
            while (i < n && nums[i] == nums[i - 1])
            {
                i++;
            }
        }
        return ret;
    }
};

寒冷的冬夜里,祝大家圣诞节快乐,平安喜乐!🎅❄️🎄

希望读者们多多三连支持

小编会继续更新

你们的鼓励就是我前进的动力!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【算法一周目】双指针(2)
题目链接:611. 有效三角形的个数 题目描述:给定一个包含非负整数的数组nums,返回其中可以组成三角形三条边的三元组个数。
HZzzzzLu
2024/11/26
880
【算法一周目】双指针(2)
【优选算法】探索双指针之美(一):双指针与单调性的完美邂逅
在上一章中我们已经认识到了双指针,在这章里我们就来探索一下当双指针和单调性遇见后会擦出怎样的火花呢?
_孙同学
2024/10/21
1030
【优选算法】探索双指针之美(一):双指针与单调性的完美邂逅
【优选算法篇】两队接力跑:双指针协作解题的艺术(下篇)
引言:通过上篇文章带大家简单了解“双指针算法”,小试牛刀。接下来将让大家感受一下双指针在解题的妙处。
熬夜学编程的小王
2024/12/24
1070
【优选算法篇】两队接力跑:双指针协作解题的艺术(下篇)
基础算法--双指针算法
通常我们讲的双指针就是用两个指针,两个指针可以是快慢指针,解决成环的问题,也可以是指向收尾的两个指针,来减小时间复杂度。双指针算法里的指针也不止是指针,在数组中也可以是数组元素的下标,这里双指针是一种思想,并不是单单指的是指针。 接下来我们用几道例题来看看双指针算法。
用户11305458
2024/10/09
1530
基础算法--双指针算法
【算法专题】双指针
其实不单单是环形链表或者是数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使⽤快慢指针的思想。快慢指针的实现方式有很多种,最常用的⼀种就是:
YoungMLet
2024/03/01
1620
【双指针算法】——还不会双指针?看这里一篇就能让你明白其中的奥妙
https://leetcode.cn/problems/move-zeroes/
用户11286421
2024/10/11
4970
【双指针算法】——还不会双指针?看这里一篇就能让你明白其中的奥妙
【刷题】双指针进阶
请看入门篇 :双指针入门 送给我们一句话: 如今我努力奔跑,不过是为了追上那个曾经被寄予厚望的自己 —— 约翰。利文斯顿
叫我龙翔
2024/03/16
990
【刷题】双指针进阶
算法专题一: 双指针
2. 快慢指针:又称为龟兔赛跑算法,其基本思想就是使用两个移动速度不同的指针在数组或链表等序列结构上移动。
用户11317877
2024/10/16
680
算法专题一: 双指针
【优先算法】专题——双指针
题目分析:题目说不要超过数组长度其实就是告诉我们不要越界,题目还告诉我们不能创建额外数组让我们就地修改原数组,我们不需要返回任何内容。
用户11375356
2024/11/25
1500
【优先算法】专题——双指针
我爱学算法之—— 感受双指针带来的快感(中)
题目描述十分简单,我们首先相当直接暴力枚举,依次判断是否满足条件就行了;但是这样时间复杂度就是O(n^3),我们需要简化一下
星辰与你
2024/12/29
840
我爱学算法之—— 感受双指针带来的快感(中)
【优选算法】——Leetcode——611. 有效三角形的个数
给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。
小李很执着
2024/06/15
1470
【优选算法】——Leetcode——611. 有效三角形的个数
【优选算法题练习】day2
11. 盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明:你不能倾斜容器。
摘星
2023/10/15
1610
【优选算法题练习】day2
我爱学算法之—— 感受双指针带来的快感(下)
我们这里借用两数之和中利用双指针算法找和为target的思路;依次固定(从左到右)给定数组中的数字i,然后利用双指针算法,在其右边区间内找到和为-i的两个数,找到返回即可。
星辰与你
2024/12/29
880
我爱学算法之—— 感受双指针带来的快感(下)
双指针算法的妙用:提高代码效率的秘密(3)
小编在昨日讲述了关于双指针算法的两个题目,今日继续分享两个题目的解析,我相信,我只要坚持每天啥刷题,算法能力终究会提高的,下面废话不多说,开始进入今天的代码时间。 正文:
用户11295429
2024/11/15
1340
双指针算法的妙用:提高代码效率的秘密(3)
【c++算法篇】双指针(下)
我们知道,三角形的满足条件是任意的两边之和大于第三边,但是如果我们已经判断了较小的两个边大于第三边,就不需要再进行剩下两组的判断,所以我们先进行排序,再进行枚举:
用户11029103
2024/05/08
1740
【c++算法篇】双指针(下)
【leetcode刷题】:双指针篇(有效三角形的个数、和为s的两个数)
题目意思很好理解:就是在一堆非负整数的数组里,随机选三个数进行搭配,然后统计这个数组中任意三个数能组成三角形的组合个数。
爱喝兽奶的熊孩子
2025/01/10
660
【leetcode刷题】:双指针篇(有效三角形的个数、和为s的两个数)
算法思想总结:双指针算法
该题的重要信息:1、不要在超过该数组的长度的位置写入元素(就是不要越界)2、就地修改(就是不能创建新数组)。3、不返回任何东西。
小陈在拼命
2024/03/16
1490
算法思想总结:双指针算法
【优选算法】四数之和(双指针算法)
前面的三数之和题如果理解透彻且代码能够自己写出来,其实这道四数之和题自己也是能够写出来的,就是这道题有一个数据溢出的问题解决一下就好了。
云边有个稻草人
2025/01/20
810
【优选算法】四数之和(双指针算法)
假期算法提升(一篇文章带你彻底学会双指针)
呀哈喽,我是结衣。 对于要参加程序设计比赛的人来说,算法永远都是一道绕不开的坎,你必须的去了解他才可以更好的去解决问题。非形式地说,算法就是任何良地计算过程,我们可以把算法看作是用于求良说明地计算问题地工具。那么今天我们学到的就是其中最基础的一种,双指针的应用。 在今天的这篇文章,我们将会了解到双指针的绝大多数题型,掌握了他们,那么你的双指针就算是过关了。文章的题目都是由易到难。在看完解题方法后请先自己敲出代码后再考代码部分哦。
Yui_
2024/10/15
1420
假期算法提升(一篇文章带你彻底学会双指针)
我和双指针的初次亲密邂逅:那一刻心跳加速
给定一个长度为 n 的整数数组 height。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i])。
Undoom
2024/10/19
1230
我和双指针的初次亲密邂逅:那一刻心跳加速
推荐阅读
相关推荐
【算法一周目】双指针(2)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验