【C++算法】双指针

news2024/11/26 1:40:30

目录

一、快乐数:

二、有效三角形的个数:

三、盛最多水的容器:

四、复写0:

五、三数之和:

总结:


一、快乐数:

题目出处:

202. 快乐数 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/happy-number/

题目说明:

输入示例:

如上图所示:

当输入一个数字的时候,经过多次变化,一定会进入一个圆,如果最后是1可以看做一个圆,里面都是1。如果不是1,那么一定会进入一个圆里面。那么会不会出现一个无限不循环的呢?答案是不会的。

证明思路:

首先,正整型最大的是2147483647,那么便于计算将9999999999代替它,那么将9999999999经过题目所给的方式计算后的结果为810,所以经过题目的操作后,其结果肯定在0~810中,所以一个数字经过811次题目所给操作后肯定会有重复的,那么就会进入一个圆

解题思路:

首先定义快慢指针,慢指针指向输入的数,快指针指向进行一次题目操作后的数字,

因为要多次进行题目所给的操作,所以就需要将题目所给操作封装成一个函数,

最后使用循环判断知直到二者相遇就结束循环,最后返回二者之一是否等于1即可

class Solution {
public:
    int func(int n)
    {
        int sum = 0;
        while(n)
        {
            int t = n % 10;
            sum += t*t;
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n) {
        int slow = n, fast = func(n);
        while(slow != fast)
        {
            slow = func(slow);
            fast = func(func(fast));
        }
        return slow == 1;
    }
};

二、有效三角形的个数:

题目出处:

611. 有效三角形的个数 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/valid-triangle-number/题目说明:

输入示例:

解题思路:

既然可以包含重复的,那么就不需要进行去重操作。

主要思路是暴力解法(将每一个情况都列举出来,之后通过三角形两边之和大于另一边进行判断),双指针在暴力解法上更加快速:(三角形最短两边之和大于最长的一边)

那么就将整个数组进行排序(因为这样的话就方便使用双指针进行操作)

需要三个变量,一个指向最左边作为短边,一个指向最右边作为最长的一边,另一个在中间的区间进行寻找能够构成三角形的三个数字。

其中两个if判断

一个if

如果最左边left和最右边right所在的值相加比第三边都长的话就证明左边的所有和right相加都比第三边大,这个时候直接进行right-left找到所有情况加到ret返回值即可,

另一个if就是左边最小的值和右边最大的值相加都小于等于最大的max,这样的话就证明left和右边所有相加都不能够构成三角形,left继续++即可

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

三、盛最多水的容器:

题目出处:

11. 盛最多水的容器 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/container-with-most-water/题目说明:

示例:

解题思路:

首先依然是双指针就定义left和right指针指向最左和最右,这里还需要宽度(right-left),高度(left和right所对应的值中小的那一个)最大体积,当前体积(如果比最大体积大就更新最大体积)

之后在循环中使用双指针,

if语句中

如果此时left所在的高度比right所在的高度小,那么就证明left~right中间的所有和此时的left组合成的容器所盛水的体积都比此时要小

所以就将left++;

如果此时left所在的高度比right所在的高度大,那么就证明left~right中间的所有和此时的right组合成的容器所盛水的体积都比此时要小

所以就将right--;

最后更新宽度,高度,此时体积和max体积比较。

循环结束后返回max体积即可

class Solution {
public:
    int maxArea(vector<int>& height) {
        int left = 0;
        int right = height.size() - 1;
        int wide = right - left;
        int high = height[left] < height[right] ? height[left] : height[right];
        int tempval = 0;
        int maxval = wide*high; 
        while(left < right)
        {
            if(height[left]<height[right])
            {
                left++;
            }
            else
            {
                right--;
            }
            wide--;
            high = height[left] < height[right] ? height[left] : height[right];
            tempval = wide*high;
            if(tempval > maxval)
            {
                maxval = tempval;
            }
        }
        return maxval;
    }
};

四、复写0:

题目出处:

1089. 复写零 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/duplicate-zeros/题目说明:

解题思路:

首先对于arr数组,复写0,如果从前往后进行复写的时候会发现无论怎样都会覆盖某些值,这样就会丢失数据,那么就需要从后往前进行复写操作。

那么既然是复写,并且数组元素确定,那么肯定这个数组中存在一个数(这个数可能是中间的某个,也可能是最后一个),在进行复写操作后就变为新数组的最后一个数,那么就需要在复写之前找到这个数。 

找到这个数之后就可以进行复写了。

找这个数的思路:

首先依然是定义两个“指针”,一个在数组0位置,另一个在数组-1位置(但是这个位置不会访问,也不能访问)接着往后进行遍历,一般情况下cur在dest的下一个,但是如果cur的位置不是0的话,两个都++,如果cur位置是0的话,就将dest向右移动两位,如果dest到最后的时候,此时cur位置就是要找的这个值。

但是有一个例外情况,就是dest最后+2后越界访问了,这样的话就在确定cur后进行边界检查

最后复写即可:

如果cur位置不是0就直接和dest交换,之后将二者向左移一个位置

如果cur位置是0就将cur和dest交换,之后将二者向左移一个位置,在将此时的dest修改为0,在将dest向左移一个位置。

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int cur = 0;
        int dest = -1;
        int n = arr.size();
        while(dest < n - 1)
        {
            //如果cur位置是0,dest就走两步,不是0就走一步
            if(arr[cur])
            {
                dest++;
            }
            else
            {
                dest += 2;
            }
            if(dest >= n - 1)
                break;
            cur++;
        }
        if(dest == n)
        {
            arr[n-1] = 0;
            cur--;
            dest-=2;
        }
        while(cur>=0)
        {
            if(arr[cur])
            {
                swap(arr[cur--],arr[dest--]);
            }
            else
            {
                swap(arr[cur--],arr[dest--]);
                arr[dest--] = 0;
            }
        }
    }
};

五、三数之和:

题目出处:

15. 三数之和 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/3sum/description/题目说明:

解题思路:

思路一:

首先进行排序,在进行暴力枚举,最后再利用容器去重

上述方法由于是暴力枚举,在本题中会超时

思路二(“双指针”法):

1、首先依然是进行排序,

2、然后分析题目,要找到三个数相加为0,其实也可以看做两个数的和等于第三个数的相反数。

3、那么就可以首先固定一个数为目标数记为ret,在这个数的后面寻找其余两个数,这两个数的和是-ret即可

注意细节:

1、题目说不能有重复的三元组,那么就需要去重操作。

去重思路:

a、容器去重,直接利用set或者unordered_set进行去重处理

b、每次找到一种结果之后将left和right指针跳过重复元素,当使用完一次双指针之后,也就是在一个ret找完后,ret也要跳过重复元素。

2、要保证不能漏

不漏比较好处理,只需要在每次找到一种结果之后,继续走完当前情况

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<vector<int>> v;
        int i = 0,n = nums.size();
        int ret = 0;
        while(i<n)
        {
            ret = nums[i];
            int left = i+1,right = n-1;
            while(left < right)
            {
                int sum = -(nums[left] + nums[right]);
                //-4 -3 -2 -1 0 1 2 3 4 5 6 7 8
                if(ret < sum) ++left;
                else if(ret > sum) --right;
                else
                {
                    v.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 v;
    }
};

总结:

双指针算法适用于一串有序的数字,能够将暴力枚举的时间复杂度降低一维,n^3->n^2

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

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

相关文章

spring task的使用场景

spring task 简介 spring task 是spring自带的任务调度框架按照约定的时间执行某个方法的工具&#xff0c;类似于闹钟 应用场景 cron表达式 周和日两者必定有一个是问号 简单案例

基于java的企业车辆管理系统设计与实现(论文+源码)-kaic

摘 要 随着经济的日益增长,车辆作为最重要的交通工具,在企事业单位中得以普及,单位的车辆数目已经远远不止简单的几辆,与此同时就产生了车辆资源的合理分配使用问题。现有的车辆管理系统存在着不足之处&#xff0c;例如系统不够稳定&#xff0c;功能不够全面。因此&#xff0c…

Python基础之转义字符

字符串转义 转义是指在字符前加一个 \ \ n 则表示原来的字符n不代表字符n 赋予了一个新的含义 变成了一个换行符 print(wu\nzj\njing) \n 会解释为一个换行符 s "wu\"zj" 双引号是用来创建一个字符串的效果 加上\后就变成了一个字符双引号 它就是一个…

如何解决 Open /etc/postfix/main.cf: Permission denied ?

最近我的 Postfix 邮件系统无法发送电子邮件&#xff0c;报错内容&#xff1a;Open /etc/postfix/main.cf: Permission denied 经过一番调查&#xff0c;我能够解决这个问题。 日志文件中发现的错误如下&#xff1a; Jun 27 12:51:02 tecadmin postfix/postfix-script[11764]…

AI大模型开发架构设计(11)——AI 大模型与提示词工程助力职场典型案例场景实战

文章目录 AI 大模型与提示词工程助力职场典型案例场景实战1 AI大模型全局架构实战剖析AI大模型常见术语AI 大模型全局架构 2 Prompt Engineering 整体应用场景剖析Prompt 提示词的三个层次Prompt 提示词的经典模板如何让 Prompt 提示词做的更好?如何让 Prompt 提示词自动优化改…

ResNet模型

使用pytoch实现 1.卷积神经网络 conv2d的参数很简单 conv2d(input_channels, output_channels,kernel_size, stride, padding) 参数分别是输入通道&#xff0c;输出通道&#xff0c;卷积核大小&#xff0c;移动步长&#xff0c;填充数量。 输入通道是特征图的深度&#xff0c…

Android上的AES加密

基础算法说明 https://www.youtube.com/watch?vlnKPoWZnNNM 虽然这个视频讲的非常详细&#xff0c;但是涉及到具体底层算法&#xff0c;大致流程 1. 将数据转成HEX或者byte array 2.将数据分层一块块等大小的数据 3.将数据和key 进行一次混合&#xff0c;加密之后的输出&…

(vue)el-tabs标签页展示el-table动态表头表格

&#xff08;vue&#xff09;el-tabs标签页展示el-table动态表头表格 效果: 代码 <el-tabs v-if"showStatistics" type"border-card"><el-tab-panev-for"(item, index) in statisticsTable":key"index":label"item.pr…

C++游戏开发指南(新改)

目录 1. 引言 2. C的基础知识 2.1 面向对象编程与游戏开发 2.2 指针与内存管理 2.3 C和其他游戏开发语言的比较 3. 游戏引擎的选择 3.1 Unreal Engine 3.2 Unity 3.3 游戏引擎对比表 4. 游戏架构设计 4.1 ECS架构 4.2 游戏循环 5. C中的图形编程基础 5.1 DirectX…

Panasonic Programming Contest 2024(AtCoder Beginner Contest 375)题解

A - Seats 思路&#xff1a;从前往后扫&#xff0c;判断有多少个.的左右各有一个# #include<bits/stdc.h> using namespace std; #define int long longint n; string s;signed main() {cin>>n;cin>>s;int cnt0;if(s.size()<3){cout<<0<<&quo…

python中双引号和单引号的区别是什么

python3中的单引号‘’和双引号“”的作用一样。 3个单引号的作用&#xff1a; 1、表示注释 #3个单引号表示注释多行gf_of_archerzon "Wang" print("archerzon的女盆友是",gf_of_archerzon) print("archerzon的女盆友是%s"%gf_of_archerzon)2…

PolarCTF靶场[web]file、ezphp WP

[WEB]file 知识点&#xff1a;文件上传漏洞 工具&#xff1a;Burp Suite、dirsearch 方法一&#xff1a; 根据页面提示&#xff0c;先用dirsearch工具扫一扫 访问/upload.php&#xff0c;发现一个上传区 在访问/uploaded/,再点击Parent Directory&#xff0c;发现链接到首页…

NVIDIA GPGPU的通信架构解析

NVIDIA GPGPU- 通信架构 写在前面 在本部分&#xff0c;我们将深入探讨NVLink、NCCL、NVSwitch和GPGPU之间的紧密联系。重点关注通信系统及其与计算的耦合性&#xff0c;以揭示Nvlink & NVSwitch System在支持NVIDIA GPGPU大规模计算和超大算力方面的重要作用。为了更好地…

新生入门季 | 学习生物信息分析,如何解决个人电脑算力不足的问题?

随着生物信息学在科研和教育中的快速普及&#xff0c;越来越多的新生开始接触基因组测序、RNA分析等复杂计算任务。然而&#xff0c;在面对这些大规模数据时&#xff0c;个人电脑的算力往往显得捉襟见肘。你是否也在为自己的笔记本性能不足而苦恼&#xff1f; 这篇文章将为你提…

【读书笔记-《30天自制操作系统》-27】Day28

本篇的内容不少&#xff0c;主要围绕着文件操作与文字显示展开。 1. alloca函数 在开发文件操作与文字显示之前&#xff0c;需要先做一些准备&#xff0c;引入alloca函数。首先看下面的代码&#xff1a; #include <stdio.h> #include "apilib.h"#define MA…

美畅物联丨剖析 GB/T 28181 与 GB 35114:视频汇聚领域的关键协议

我们在使用畅联云平台进行视频汇聚时&#xff0c;经常会用的GB/T 28181协议&#xff0c;前面我们写了关于GB/T 28181的相关介绍&#xff0c;​ 详见《畅联云平台&#xff5c;关于GB28181你了解多少&#xff1f;》。 ​最近也有朋友向我们咨询GB 35114协议与GB/T 28181有什么不同…

基于STM32的智能运输机器人设计

引言 本项目设计了一个基于STM32的智能运输机器人&#xff0c;能够自动识别路径、避开障碍物&#xff0c;并根据用户的指令将物品运输到指定地点。该机器人集成了超声波传感器、红外传感器、无线通信模块等&#xff0c;通过STM32对电机的控制&#xff0c;实现平稳、智能的运输…

【深度学习】RNN的简单实现

目录 1.RNNCell 2.RNN 3.RNN_Embedding 1.RNNCell import torchinput_size 4 hidden_size 4 batch_size 1idx2char [e, h, l, o] x_data [1, 0, 2, 2, 3] # 输入&#xff1a;hello y_data [3, 1, 2, 3, 2] # 期待&#xff1a;ohlol# 独热向量 one_hot_lookup [[1, …

滑雪——记忆化搜索

题目 代码 //#pragma GCC optimize(3)#include <bits/stdc.h> const int N 310; using namespace std; int dx[4] {-1, 0, 1, 0}, dy[4] {0, 1, 0, -1}; int ans; int g[N][N]; int r, c; int f[N][N]; int dfs(int x, int y) {if(~f[x][y]) return f[x][y];f[x][y] …

TikTok直播带货话术分享,轻松实现销量翻倍

随着TikTok直播带货的不断壮大&#xff0c;越来越多的国内用户开始尝试使用英语进行直播带货。这不仅能够吸引国际观众&#xff0c;还能够扩大市场和提升品牌影响力。 TikTok直播通用带货话术 1. 开场白 开场时&#xff0c;主播可以用热情的语言吸引观众的注意力&#xff1a;…