初识算法 · 双指针(1)

news/2024/10/5 9:37:01 标签: 算法

目录

前言:

双指针算法

题目一:

​编辑

题目二:


前言:

本文作为算法部分的第一篇文章,自然是少不了简单叭叭两句,对于算法部分,多刷是少不了,我们刷题从暴力过度到算法解法,自然是一个很痛苦的过程,而算法本身的思考是很重要的,所以算法部分的介绍大多都是通过题目直接介绍,以题目来灌注算法知识,因为每人对于算法的接受程度有限,每篇大多都是两题左右,对于难题部分,大多时候只会出一道,并且均以leetcode作为题目来源,本文都会以最优质的解法来介绍不同的算法通过三个部分来解决题目,题目解析,算法原理,算法编写。


双指针算法

题目一:

样例为:

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

题目解析:

给定一个数组,移动0到末尾,不必考虑0的相对顺序,但是要保持非零的相对顺序。

如果不使用双指针,有很多解法,比如我们可以将所有的非零元素移动到最开始,但是移动一次,就需要遍历一次,时间复杂度是接近于O(N^2)的,因为不能数组,这是一种暴力解法,那么我们如何使用双指针呢?

算法原理:

通过使用双指针,将数组划分为三个区域:

[0,dest]划分为非零元素的区域,[dest,cur]划分为0元素的区域,[cur,end]划分为还没有遍历的区域。既然是使用双指针算法,我们自然需要定义两个“指针”,可是这里实际上不是指针,这里我们需要对双指针有一个形象的认识,双指针并不是真正的用指针,它们代表的只是形象的指向两个元素而已,这里的指针可是是一个数,可以是数组,可以是任何能代替指向的东西。

这里是数组下标,所以定义两个下标是必不可少的。

然后就是进行划分区域,二者都是从0开始划分,dest我们不知道如何定义可以先不管,cur遍历数组,找到非零的元素,就给dest,那么怎么给呢?dest可以从-1开始,因为cur就是从0开始的,找到了非零元素,dest++进行交换,cur正常走即可。

算法编写:

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

就过啦,可能算法代码出乎你想象的简单,习惯就好。

简单的分析一下时间复杂度吧,一次遍历,O(N),如果暴力是平方,这优化的就很不错了。

题目链接:283. 移动零 - 力扣(LeetCode)

题目二:

样例为:

输入:n = 19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1

题目解析:

题目名为快乐数,让我们看看题目有多快乐吧!

快乐数的定义为将一个数多次等于该数上的每一位数字的平方相加,如果经过多次变化,数字可以变为1,那么就是快乐数,但是如果是一直无线循环没有变成1,那么该数就不是快乐数。对于这种题目就没有暴力解法了,因为真要暴力的话很有可能套死循环出不去了。所以我们直接进入到算法原理部分。

算法原理:

我们不妨画图,看看变化是怎么个事儿:

对于19来说,经过了4次变化就到1,那么对于2来说,经过多次变化,出现了和第一次变化一样的值,4。

那么我们可不可以理解2在变化的时候出现了环,且数的变化出不了这个环,所以它不是快乐数,那么好像看起来也没啥啊,19也没有出现环,可是,如果我们换个角度,19变化的时候,是不是出现了一个环,环里面只有1呢?

这时候相信大部分人已经明了了,我们只需要判断环里面是不是1即可,即我们可以使用两个指针,一个走的快,一个走的慢,二者是一定相遇的,相遇的时候,看相遇的点是不是1就可以了。

那么就有第二个问题了,为什么一定会出现环呢?

这里要使用到的是我们之前未曾听闻的一个数学原理,鸽巢原理

我们使用鸽巢原理来证明一定会出现环状:

这是Leetcode中告诉的n最大的取值,那么:

这是最大的取值,我们不妨这样,一共有10个数字,我们再大一点,10个9,也就是说,我们计算一下9999999999经过一次变化之后的取值,变化之后的取值是810,也就是说,变化之后最大的值一定不会超过810。不妨定义函数F(x)等于一次变化,那么一个数经过811变化,也就是产生了811个数,但是总的区间只有810,那么一定有一个数是重复的,这就是鸽巢原理的应用。

算法编写:

class Solution 
{
public:
    int _isHappy(int num)
    {
        int ans = 0,sum = 0;
        while(num)
        {
            sum = num % 10;
            ans = ans + sum * sum;
            num /= 10;
        }
        return ans;
    }
    bool isHappy(int n) 
    {
        int slow = n,fast = n;
        while(1)
        {
            slow = _isHappy(slow);
            fast = _isHappy(_isHappy(fast));
            if(slow == fast)
            {
                if(slow == 1)
                return true;
                else
                return false;
            }
        }
    }
};

一个函数,_ishappy对应函数F(x),那么快慢指针,就是一个变化两次,一个变化一次,当它们相等的时候,判断即可,这里也应证了双指针的算法并不是真的使用指针,它更多的只是一种思想而已!!


今日算法到这里了,感谢阅读!


http://www.niftyadmin.cn/n/5690852.html

相关文章

注册键AlwaysInstallElevated

原理 允许低权限用户以System权限安装文件。如果启用此策略设置项&#xff0c;那么任何权限的用户都以NT Authority\System权限来安装恶意的MSI文件。 windows install是windows操作系统的组件之一&#xff0c;专门用来管理配置软件服务。木马格式&#xff08;.msi&#xff09…

我博客网站又遭受CC攻击了,记录一下

2024.9.29凌晨4点攻击开始&#xff0c;攻击目标是我的图床tc.zeruns.tech和博客blog.zeruns.tech&#xff0c;图床用的cdn是多吉云融合CDN&#xff0c;流量被刷了20GB左右就触发峰值关闭CDN了&#xff0c;HTTPS请求次数被刷了1.1亿次&#xff0c;因为设置了QPS&#xff0c;实际…

【NIO基础】基于 NIO 中的组件实现对文件的操作(文件编程),FileChannel 详解

目录 1、FileChannel (1&#xff09;获取 FileChannel (2&#xff09;读取文件 (3&#xff09;写入文件 (4&#xff09;关闭通道 (5&#xff09;当前位置与文件大小 (6&#xff09;强制写入磁盘 2、两个 FileChannel 之间的数据传输 (1&#xff09;使用 transferTo()…

Java中的数据格式转换:JSON、XML与Protobuf的应用与选择

Java中的数据格式转换&#xff1a;JSON、XML与Protobuf的应用与选择 大家好&#xff0c;我是微赚淘客返利系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们要聊的主题是Java开发中经常涉及到的一个重要问题——数据格式转换。…

《C++游戏人工智能开发:开启智能游戏新纪元》

在当今的游戏世界中&#xff0c;人工智能&#xff08;AI&#xff09;已经成为了不可或缺的一部分。它能够为游戏增添深度、挑战性和真实感&#xff0c;让玩家沉浸其中&#xff0c;享受前所未有的游戏体验。而对于 C开发者来说&#xff0c;如何在 C中实现高效的游戏人工智能开发…

【HTTP(3)】(状态码,https)

【认识状态码】 状态码最重要的目的&#xff0c;就是反馈给浏览器:这次请求是否成功&#xff0c;若失败&#xff0c;则出现失败原因 常见状态码: 200:OK&#xff0c;表示成功 404:Not Found&#xff0c;浏览器访问的资源在服务器上没有找到 403:Forbidden&#xff0c;访问被…

webpack信息泄露

先看看webpack中文网给出的解释 webpack 是一个模块打包器。它的主要目标是将 JavaScript 文件打包在一起,打包后的文件用于在浏览器中使用,但它也能够胜任转换、打包或包裹任何资源。 如果未正确配置&#xff0c;会生成一个.map文件&#xff0c;它包含了原始JavaScript代码的映…

openpnp - 视觉原点的位置要离设备的软限制点远一点

文章目录 openpnp - 视觉原点的位置要离设备的软限制点远一点笔记备注END openpnp - 视觉原点的位置要离设备的软限制点远一点 笔记 最开始的视觉原点&#xff0c;是在设备X 0, Y 0的附近位置&#xff0c;粘了一块20x20x20的铝块&#xff0c;铝块上面贴着用黑塑料皮打印的1…