【基础算法】双指针

news2024/12/28 18:48:10

 1.移动零

 移动零

 思路:

利用双指针算法

cur:从左往右扫描数组,遍历数组

dest:处理好的区间包括dest

dest初始化为-1,因为刚开始dest前应该没有非零元素。

即将非零元素移到dest之前即可

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        for(int cur = 0, dest = -1; cur < nums.size(); cur++)
        {
            if(nums[cur]) //非零元素
            {
                swap(nums[++dest], nums[cur]);
            }
        }
    }
};

 2.复写零

 复写零

 思路:

要注意的是从“异地”操作,优化为“就地”操作。即题目要求是只能在就地操作,那我们就可以先尝试模拟在异地操作使用双指针算法,然后进行优化到就地双指针。

就地进行模拟时,应该从前往后还是从后往前,我们发现从前往后会覆盖掉我们需要的内容,所以我们要从后往前开始复写。

但又有个问题,我们并不知道最后要复写的内容是哪个!

所以我们要先从前开始寻找最后一个需要复写的元素

这时我们发现一个特例,这就是边界情况。dest走到了n的位置

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int cur = 0, dest = -1, n = arr.size();
        //寻找最后一个需要复写的元素
        while(cur < n)
        {
            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])
            {
                arr[dest--] = arr[cur];
            }
            else
            {
                arr[dest--] = 0;
                arr[dest--] = 0;
            }
            cur--;
        }

    }
};

3.快乐数 

快乐数

思路:利用快慢指针解决

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

4.盛最多水的容器

盛最多水的容器

思路:利用对撞指针解决,强度单调性

class Solution {
public:
    int maxArea(vector<int>& height) {
        int left = 0, right = height.size() - 1;
        int ret = 0;
        while(left < right)
        {
            int v = min(height[left], height[right]) * (right - left);
            ret = max(ret, v);

            if(height[left] < height[right]) left++;
            else right--;
        }
        return ret;
    }
};

5.有效三角形的个数

有效三角形的个数

 

思路: 

对撞指针,利用单调性

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;
    }
};

6.和为s的两个数

查找总价格为目标值的商品

 

思路:

对撞指针,单调性

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

7.三数之和

三数之和

 

思路:

对撞指针 ,使用二数之和思想

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ret;
        sort(nums.begin(), nums.end());
        int n = nums.size();
        for(int i = 0; i < n; )  // i是固定数a
        {
            if(nums[i] > 0) break;//常数级优化
            int left = i + 1, right = n - 1, target = -nums[i];//寻找和等于target的两数
            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--;
                    //去重 left right
                    while(left < right && nums[left] == nums[left - 1]) left++;
                    while(left < right && nums[right] == nums[right + 1]) right--;
                }
                
            }
            //去重i
            i++;
            while(i < n && nums[i] == nums[i - 1]) i++;
        }
        return ret;
    }
};

8.四数之和

四数之和

思路:

使用三数之和思想

 

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> ret;
        sort(nums.begin(), nums.end());
        int n = nums.size();
        for(int i = 0; i < n;)
        {
            for(int j = i + 1; j < n;)
            {
                int left = j + 1, right = n - 1;
                //防止t数据溢出,开long long
                long long t = (long long)target - nums[i] - nums[j];
                while(left < right)
                {
                    if(nums[left] + nums[right] < t) left++;
                    else if(nums[left] + nums[right] > t) right--;
                    else{
                        ret.push_back({nums[i], nums[j], nums[left], nums[right]});
                        //不漏
                        left++, right--;
                        //去重 left 和 right
                        while(left < right && nums[left] == nums[left - 1]) left++;
                        while(left < right && nums[right] == nums[right + 1]) right--;
                    }
                }
                //去重j
                j++;
                while(j < n && nums[j] == nums[j - 1]) j++;
            }
            //去重i
            i++;
            while(i < n && nums[i] == nums[i - 1]) i++;
        }
        return ret;
    }
};

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

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

相关文章

BFS解决FloodFill算法:(Leetcode:733. 图像渲染)

题目链接&#xff1a;733. 图像渲染 - 力扣&#xff08;LeetCode&#xff09; 使用广度优先遍历算法解决该问题&#xff1a; 从初始位置开始搜索&#xff0c;初始位置符合条件就入栈&#xff0c;并修改初始位置值。初始位置出栈。 再从初始位置开始广度优先搜索&#xff08;…

【机器学习300问】78、都有哪些神经网络的初始化参数方法?

在训练神经网络时&#xff0c;权重初始化是确保良好收敛的关键步骤之一。不合适的初始化方法可能会导致梯度消失或爆炸&#xff0c;特别是在深层网络中。那么都有哪些神经网络的初始化参数方法呢&#xff1f;选择它这些方法的原则是什么&#xff1f; 一、常用神经网络初始化参…

Kubernetes(k8s)的概念以及使用

k8s的概念&#xff1a; K8s是指Kubernetes&#xff0c;是一个开源的容器编排和管理平台。它最初由Google开发&#xff0c;并于2014年将其开源。Kubernetes旨在简化容器化应用程序的部署、扩展和管理。 Kubernetes提供了一种可靠且可扩展的平台&#xff0c;用于管理容器化应用…

怎样才能迅速了解一个产品的业务流程?

很多小伙伴经常问我&#xff0c;刚进入一家新的企业&#xff0c;想要快速了解产品的业务流程&#xff0c;不知从何下手。主要是因为&#xff0c;有的企业根本没有文档可看&#xff1b;还有的企业有文档&#xff0c;但是记录的比较凌乱&#xff0c;想要从中找出点头绪来&#xf…

【Python-装饰器】

Python-装饰器 ■ 简介■ 装饰器的一般写法&#xff08;闭包写法&#xff09;■ 装饰器的语法 (outer写法) ■ 简介 装饰器其实是一种闭包&#xff0c; 功能就是在不破坏目标函数原有的代码和功能的前提下为目标函数增加新功能。 ■ 装饰器的一般写法&#xff08;闭包写法&am…

2024年前端技术发展趋势

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

程客有话说05 | 吕时有:在GIS行业深耕13年,做梦做出来了数学竞赛题,这是让我最开心的事

《程客有话说》是我们最新推出的一个访谈栏目&#xff0c;邀请了一些国内外有趣的程序员来分享他们的经验、观点与成长故事&#xff0c;我们尝试建立一个程序员交流与学习的平台&#xff0c;也欢迎大家推荐朋友或自己来参加我们的节目&#xff0c;一起加油。 本期我们邀请的程…

使用Docker搭建本地Nexus私有仓库

0-1开始Java语言编程之路 一、Ubuntu下Java语言环境搭建 二、Ubuntu下Docker环境安装 三、使用Docker搭建本地Nexus Maven私有仓库 四、Ubuntu下使用VisualStudioCode进行Java开发 你需要Nexus Java应用编译构建的一种主流方式就是通过Maven, Maven可以很方便的管理Java应用的…

网盘兼职真的能月入过万吗?你适合做哪种网盘分享牛?

1. 分享大容量文件&#xff1a; 提供常见软件安装包、系统镜像、游戏资源等常用的大容量文件&#xff0c;以满足用户的需求。 创建分类目录&#xff0c;便于用户浏览和查找所需文件。 编写详细的文件描述&#xff0c;包括文件版本、适用系统、安装方法等信息&#xff0c;帮助用…

Promise.all 的方法还没执行完就执行了.then

碰见一个问题&#xff0c;接盘了一个有问题的页面修改。 改变日期后 查询很多数据再去重新加载页面上的数据显示相关的组件。 问题就来了。 加载异常捏…… 最后我一通查&#xff1a; 重点来了 是因为这个Promise.all(数组)&#xff0c;里边这个数组的问题。现在是在数据中…

XYCTF 部分wp及学习记录

1.ezmd5 根据题目提示 我们知道应该是要上传两张md5值相同的图片 根据原文链接&#xff1a;cryptanalysis - Are there two known strings which have the same MD5 hash value? - Cryptography Stack Exchange 把保存下来的图片上传一下 得到flag 2.ezhttp 根据原文链接&…

STM32H7的LCD控制学习和应用

STM32H7的LCD控制 LTDC基础硬件框图LTDC时钟源选择LTDC的时序配置LTDC背景层、图层1、图层2和Alpha混合LTDC的水平消隐和垂直消隐LCD的DE同步模式和HV同步模式的区别区分FPS帧率和刷新率避免LTDC刷新撕裂感的解决方法 驱动示例分配栈的大小MPU和Cache配置初始化SDRAM初始化LCD应…

鸿蒙 harmonyos 线程 并发 总结 async promise Taskpool woker(三)多线程并发 Worker

Worker Worker是与主线程并行的独立线程。创建Worker的线程称之为宿主线程&#xff0c;Worker自身的线程称之为Worker线程。创建Worker传入的url文件在Worker线程中执行&#xff0c;可以处理耗时操作但不可以直接操作UI。 Worker主要作用是为应用程序提供一个多线程的运行环境…

办公设备租赁行业内卷瞎扯

办公设备租赁行业内卷瞎扯 最近听到很多同行抱怨&#xff0c;现在市场太卷了&#xff0c;真的有点到了卷不死就往死里卷的节奏&#xff0c;让大家都开始想换地方&#xff0c;或者转行。但是今天&#xff0c;我想从另外一个角度聊一下这个问题&#xff0c;分析一下&#xff0c;…

苍穹外卖day9 (1)用户端历史订单

文章目录 前言用户端历史订单1. 查询历史订单1.1 业务规则1.2 接口设计1.3 代码实现 2. 查询历史订单详情2.1 接口设计2.2 代码实现 3. 取消订单3.1 业务规则3.2 接口设计3.3 代码设计 4. 再来一单4.1 业务规则4.2 接口设计4.3 代码实现 前言 用户端对历史订单的操作&#xff…

机器人系统开发ros2-基础学习16-使用 rosdep 管理依赖关系

1. what is rosdep? rosdep是一个依赖管理实用程序&#xff0c;可以与包和外部库一起使用。它是一个命令行实用程序&#xff0c;用于识别和安装依赖项以构建或安装包。 其本身rosdep并不是一个包管理器&#xff1b;它是一个元包管理器&#xff0c;它使用自己的系统知识和依赖…

Day10案例分页查询,条件查询

对要求进行逻辑分析,传递固定参数{page,pagesize}任意参数{name,gender,begin,end},返回总记录数以及当前页码的记录 不使用pagehelper插件,首先完成SQL语句 SQL语句 //固定头 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLI…

SQL-DML数据操纵语言(Oracle)

文章目录 DML数据操纵语言常见的字段属性字符型字段属性char(n)varchar2(n)/varchar(n) 数值型字段属性number([p],[s]int 日期型字段属性DATEtimestamp 如何查看字段属性增加数据INSERT快捷插入 删除数据DELETE修改数据UPDATE DML数据操纵语言 定义 是针对数据做处理&#xf…

JavaScript中的map()方法详解

1. map() 的返回值是一个新的数组&#xff0c;新数组中的元素为 “原数组调用函数处理过后的值” 2. 简单使用&#xff1a;遍历整个数组&#xff0c;将大于4的元素乘以2 const array [2, 3, 4, 4, 5, 6]console.log("array",array) const map array.map(x > {…

【THM】Linux Privilege Escalation(权限提升)-初级渗透测试

介绍 权限升级是一个旅程。没有灵丹妙药,很大程度上取决于目标系统的具体配置。内核版本、安装的应用程序、支持的编程语言、其他用户的密码是影响您通往 root shell 之路的几个关键要素。 该房间旨在涵盖主要的权限升级向量,并让您更好地了解该过程。无论您是参加 CTF、参加…