【基础算法】双指针

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2016年新华三杯复赛实验试题

2016年新华三杯复赛实验试题 拓扑图 配置需求 考生根据以下配置需求在 HCL 中的设备上进行相关配置。 以太网接口配置 将 S1、S2 的以太网接口 G1/0/1 至 G1/0/16 的模式用命令 combo enable copper 激活为电口。 虚拟局域网 为了减少广播&#xff0c;需要规划并配置 VLA…

浏览器工作原理与实践--HTTPS:浏览器如何验证数字证书

你好&#xff0c;我是李兵。 在《HTTPS&#xff1a;让数据传输更安全》这篇文章中&#xff0c;我们聊了下面几个问题&#xff1a; HTTPS使用了对称和非对称的混合加密方式&#xff0c;这解决了数据传输安全的问题&#xff1b; HTTPS引入了中间机构CA&#xff0c;CA通过给服务器…

重生奇迹mu卷轴有什么用

问题一&#xff1a;重生奇迹mu里面的国王卷轴有什么用啊?创造宝石怎么用啊?国王卷不晓得~~宝石用来创造果实的。&#xff08;属性果实&#xff09; 问题二&#xff1a;请问重生奇迹mu里国王卷轴去哪弄&#xff1f;天空之城有&#xff0c;废墟1和2也有&#xff0c;遗址230也有…

付费SSL证书比免费SSL证书好在哪?

1. 身份证明更权威&#xff1a;付费证书可进行深度身份验证&#xff0c;让访客知道你的网站是真实、合法的公司运营&#xff0c;尤其高级证书能在浏览器地址栏显示公司名&#xff0c;让人一看就放心。 2. 适用范围广&#xff1a;有单域名、多域名、通配符等多种证书类型&#x…

基于SpringBoot的“幼儿园管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“幼儿园管理系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 个人信息界面图 缴费信息管理界…

重温javascript --(一)值的介绍

值的介绍 一、 值类型&#xff1a; 原始值 stack栈: 遵循后进先出原则&#xff0c;中主要存放一些基本类型的变量和对象的引用。如&#xff1a;Number String Boolean undefined null symbol BigInt 栈内不可修改值&#xff0c;内存满才会实现二次值覆盖 引用值 heap堆&#x…

C盘满了如何清理

1.更改位置 &#xff08;1&#xff09;找到要更改的用户 &#xff08;2&#xff09;找到要更改的部分&#xff0c;右键点击“属性” &#xff08;3&#xff09;选择“位置”——“移动”——选择要移动的盘及地方 点击“确定”——“是”&#xff0c;等待迁移完成

STL_vector源码剖析

STL vector STL2.91源码地址: https://github.com/lewischeng-ms/sgi-stl 侯捷老师用的是 2.91,不同版本的STL差异很大&#xff0c;靠后版本的STL用了太多typedef以及继承关系&#xff0c;导致可读性很差。 本文参考博客: https://blog.csdn.net/weixin_45389639/article/detai…

Docker NetWork (网络)

Docker 为什么需要网络管理 容器的网络默认与宿主机及其他容器都是相互隔离的&#xff0c;但同时我们也要考虑下面的一些问题&#xff0c; 比如 多个容器之间是如何通信的容器和宿主机是如何通信的容器和外界主机是如何通信的容器中要运行一些网络应用(如 nginx、web 应用、数…

【Linux系统编程】第七弹---权限管理操作(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、修改文件权限的做法(一) 2、有无权限的表现 总结 上一弹我们讲解了Linux权限概念相关的知识&#xff0c;但是我们只知道有…

设计模式学习笔记 - 开源实战四(中):剖析Spring框架中用来支持扩展的设计模式

概述 上篇文章&#xff0c;学习了 Spring 框架背后蕴含的设计思想&#xff0c;比如约定优于配置、低侵入松耦合、模块化轻量级等等。这些设计思想可以借鉴到其他框架开发中&#xff0c;在大的设计层面提高框架的代码质量。 除了上篇文章降到的设计思想&#xff0c;实际上&…

yolov8 裁剪检测结果

yolov8 裁剪检测结果 1. 基础2. 图片批量裁剪2.1 检测裁剪2.2 分割裁剪 3. 视频裁剪3.1 检测裁剪3.2 分割裁剪3.3 实时裁剪 4. 源码 1. 基础 本项目是在 WindowsYOLOV8环境配置 的基础上实现的 思路&#xff1a;将检测得到的物体边框提取&#xff0c;然后边框裁剪原图&#xf…

Python网络数据抓取(3):Requests

引言 在这一部分&#xff0c;我们将探讨Python的requests库&#xff0c;并且利用这个库来进行网页数据抓取。那么&#xff0c;我们为何需要这个库&#xff0c;以及怎样利用它呢&#xff1f; requests库是广受大家欢迎的一个库&#xff0c;它是下载次数最多的。这个库使我们能够…

直流负载在新能源领域的作用有哪些

直流负载在新能源领域的作用主要体现在以下几个方面&#xff1a; 新能源如太阳能、风能等&#xff0c;其发电过程中产生的电能为直流电。传统的电力系统主要采用交流电&#xff0c;因此在新能源并网时需要进行逆变器转换。然而&#xff0c;逆变器在转换过程中会存在一定的能量损…

设计模式-模板模式

模板设计模式 定义 在模板模式中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。 简单来说,有多个子类共有的方法,且逻辑相同,可以考虑作为模板方法。 模板的价值就在于骨架的定义,骨架内部将问题…

手写基于redis-lua脚本实现分布式id生成器starter

手写基于redis-lua脚本实现分布式id生成器starter 文章目录 1.前言2.实现思路2.1lua脚本的特性2.2 了解三个redis命令2.3集群自增序列实现原理2.4三种实现思路2.4.1 实现思路一2.4.2 实现思路二2.4.3实现思路三 3.项目工程目录4.源码仓库地址5.依赖及使用配置5.1依赖5.2nacos配…

科研基础与工具(论文写作)

免责申明&#xff1a; 本文内容只是学习笔记&#xff0c;不代表个人观点&#xff0c;希望各位看官自行甄别 参考文献 科研基础与工具&#xff08;YouTube&#xff09; 学术写作句型 Academic Phrase bank 曼彻斯特大学维护的一个网站 写论文的时候&#xff0c;不不知道怎么…

机器学习基础-PR\ROC\F1

1 1 、ROC曲线2 、PC曲线3、F14 、正负样本不均衡时怎么选择 1 、ROC曲线 就是TPR 与FPR 曲线 如图&#xff0c;就是根据阈值不同&#xff0c;我们看我们的二分类器的结果&#xff0c;根据结果算出TPR(真阳性)与FPR(假阳性)&#xff0c;最好的情况就是如图&#xff0c;我们的…

2024年三支一扶报名照上传要求很严格

2024年三支一扶报名照上传要求很严格

2024年最新版云开发cms开通步骤,开始开发微信小程序前的准备工作,认真看完奥!

小程序官方有改版了&#xff0c;搞得石头哥不得不紧急的再新出一版&#xff0c;教大家开通最新版的cms网页管理后台 一&#xff0c;技术选型和技术点 1&#xff0c;小程序前端 wxml css JavaScript MINA原生小程序框架 2&#xff0c;数据库 云开发 云数据库 云…