【leetcode】双“指针”

news2024/11/17 0:22:48

 标题:【leetcode】双指针

水墨不写bug

我认为 讲清楚为什么要用双指针 比讲怎么用双指针更重要


(一)快乐数


编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

示例 1:

输入: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

示例 2:

输入:n = 2
输出:false

提示:

  • 1 <= n <= 2^31 - 1

题解:

        记快乐数转换的对应关系为f,每一次对应关系f处理后,相当于指针向后移动一次;

        由于一个数被 f  对应关系的映射后得到数的过程是不可逆转的-->【100 的得到方法不止一种:f(68) = 100;f(86) = 100, 所以知道f处理后的结果是100,但是无法确定f处理的源(原)数是谁】

        根据这一特征,我们可以想象一个数据结构,它类似于单链表,由此可以联想到我们之前已经做过的问题:

        链表是否成环 :链表可以仅仅是一条单链,也可以是像 “6” 一样链表,当环达到最大时,链表就成了 “0” 形。

        本题  可以 类比 判断链表是否有环 的思路,但是一种情况可以忽略:一条单链表。

为什么可以忽略?

在这条“链表”中,只可能存在 “1” 或者不存在 “1” 两种情况。

        如果存在“1”,由于对“1”进行 f 对应关系的映射后仍然等于 “1”,于是 “1” 单独成环

        如果不存在 “1”,对任意一个数,都可经过有限次f变换后得到它本身。

        (现在证明:对任意一个数,都可经过有限次f变换后得到它本身。

                   int类型的范围的数量级是10^9级【10亿级】,最大的int值小于9999999999,这个值经过f变换后得到的值——9^2+9^2+9^2+9^2+9^2+9^2+9^2+9^2+9^2=729;

由于规定的输入为正整数,这意味着f的值域为[1,729],考虑到整数平方后得到的结果一定是整数,所以一个数经过最多729次变换后,它的取值取便了[1,729]的任意值,如果再进行一次f变换,得到的结果一定会与之前的值重复,命题的证。)

 为什么选择双指针?

        经过分析,可以知本题的数据结构是一个 “6” 形的 “链表”,正常的遍历无法得到终止,根据  链表是否成环 的经验,可以想到用快慢指针的速度差来判断,如果在“链表中存在 “1””,那么两指针会在“1”相遇;否则,两指针会在环中的一个随机位置相遇。

(具体实现f函数名称为Bitsum) 

class Solution {
public:
    
    //实现思路:取到这个数的每一位,平方后加到sum中;
    int Bitsum(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 = Bitsum(n);
        while(slow!=fast)
        {
            slow = Bitsum(slow);
            fast = Bitsum(Bitsum(fast));
        }
    return slow == 1;
    }
};

(二)盛水最多的容器


        给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

        找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

        返回容器可以储存的最大水量。

说明:你不能倾斜容器。

示例 1:

输入:[1,8,6,2,5,4,8,3,7]
输出:49 
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例 2:

输入:height = [1,1]
输出:1

提示:

  • n == height.length
  • 2 <= n <= 10^5
  • 0 <= height[i] <= 10^4

如果解决一道题?

        首先,我会先理解这道题,通过分析示例,彻底理解题目的要求;

        其次,我最先想到的是暴力求解,为什么?通过分析历年大赛的标准答案解法,最优解法往往是在暴力求解的基础上,优化暴力求解来得到的。优先考虑暴力解法,再通过优化暴力求解算法来得到更优的算法;另外,对于暴力求解算法,一些特殊测试点往往是会超时的,没有办法得到高分;

        然后,分析时我发现这道题可以利用双指针来避免一些不必要的枚举结果,也就是上述的优化——优化是从多种层面的,需要一些经验积累。

        最后,自己写一些测试点和结果,对照写好的程序,在纸上一步一步走读代码;这些测试点的选取要考虑全面,防止漏情况。

        根据暴力求解算法,可以在数组中选择两个下标不重复的数,用较小的数 * 两数下标之差就是体积V,记录所有的V,最终返回最大的V即可;

        固定一个下标(left),让另一个下标(right)向右遍历,遍历完后,left++,类推;

我们把本题抽象为桶:

         既然存储最多的水,我们我们直接在遍历的过程中舍去 “短板”不就行了吗?留下最长的两个板,得到的结果V不就是最大的吗?

{               

                if(height[left] >= height[right])
                       right--;
                else
                       left++;

}

        这是有人会有疑问,板长了,但是不能保证宽度大啊,V要大,前提是痛的桶壁板子和桶的内径都很大。

        确实是这样的,但是不要忘了,我们还有这两句:

 {

                int v = min(height[left],height[right])*(right-left);
                ret = max(ret,v);

}

        由于ret在每次变更桶壁后都会更新,并且会选择较大的V覆盖原值;

        那么,就相当于在 不断增长桶壁的同时也可保存V在一系列变化中的最大值;

class Solution {
public:

    int maxArea(vector<int>& height) {
        int left = 0,right = height.size()-1,ret = 0;

        while(left < right)
        {
            int v = min(height[left],height[right])*(right-left);
            ret = max(ret,v);
            if(height[left] >= height[right])
                right--;
            else
                left++;
        }
        return ret;
    }
};

(三)有效三角形个数

给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。

示例 1:

输入: nums = [2,2,3,4]
输出: 3
解释:有效的组合是: 
2,3,4 (使用第一个 2)
2,3,4 (使用第二个 2)
2,2,3

示例 2:

输入: nums = [4,2,3,4]
输出: 4

提示:

  • 1 <= nums.length <= 1000
  • 0 <= nums[i] <= 1000
class Solution {
public:

static int my_cmp(const void*a,const void*b)
{
    return *((int*)a) - *((int*)b);
}
    int triangleNumber(vector<int>& nums)
    {
        int count = 0;
        int pmax = nums.size()-1,left = 0,right = pmax - 1;
        
        qsort(&nums[0],nums.size(),sizeof(nums[0]),my_cmp);
        for(; pmax>=2 ;pmax--)
        {
            left = 0,right = pmax - 1;
            while(left < right)
            {
                if(nums[left] + nums[right] > nums[pmax]) 
                    {count +=(right-left);--right;}
                else {++left;}
            }
        }
        
        return count;
    }
};

(四)总和为目标值的两个数

购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品的价格总和刚好是 target。若存在多种情况,返回任一结果即可。

示例 1:

输入:price = [3, 9, 12, 15], target = 18
输出:[3,15] 或者 [15,3]

示例 2:

输入:price = [8, 21, 27, 34, 52, 66], target = 61
输出:[27,34] 或者 [34,27]

提示:

  • 1 <= price.length <= 10^5
  • 1 <= price[i] <= 10^6
  • 1 <= target <= 2*10^6
class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target) {
        
        int left = 0,right = price.size()-1;
        while(1)
        {
            int sum = price[right] + price[left];
            if( sum> target) right--;
            else if(sum < target) left++;
            else break;
        }
        vector<int> it = {price[left],price[right]};
        return it;
    }
};

完~

未经作者同意禁止转载

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

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

相关文章

centos7.9安装mysql

1. 概述 官网&#xff1a;https://www.mysql.com/ MySQL是一个关系型数据库管理系统&#xff0c;由瑞典 MySQL AB 公司开发&#xff0c;MySQL是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的RDBMS (Relational Database Management S…

Linux下线程池详解与实现:提升多任务处理效率的关键

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;マイノリティ脈絡—ずっと真夜中でいいのに。 0:24━━━━━━️&#x1f49f;──────── 4:02 &#x1f504; ◀…

【教程】谈一谈 IPA 上传到 App Store Connect 的几种方法

引言 在应用开发过程中&#xff0c;将应用程序上传到 App Store Connect 是一个关键的环节。本文将探讨几种常见的 IPA 文件上传方法&#xff0c;包括 Xcode、Application Loader、altool、Appuploader以及Transporter。通过本文的介绍和指导&#xff0c;读者将能够了解不同的…

基于springboot+vue+Mysql的超市进销存系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

SpringCloud学习笔记二:服务间调用

微服务中&#xff0c;很多服务系统都在独立的进程中运行&#xff0c;通过各个服务系统之间的协作来实现一个大项目的所有业务功能。服务系统间 使用多种跨进程的方式进行通信协作&#xff0c;而RESTful风格的网络请求是最为常见的交互方式之一。 spring cloud提供的方式&#…

基于springboot实现在线拍卖系统项目【项目源码+论文说明】

基于springboot实现在线拍卖系统演示 摘要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍…

jsp指令和动作

1.page指令&#xff1a;描述页面信息 pageENcoding:软件编码 contentType&#xff1a;浏览器编码 2.include指令&#xff1a;将多个网页合成一个网页&#xff0c;静态包含网页 问题&#xff1a;1.在网页源代码中&#xff0c;会形成错误的多遍代码&#xff0c;将主页面代码和…

MySQL中如何进行多表查询

目录 一、子查询 1.什么是子查询 2.注意事项 二、联结查询 1.什么是联结 2.内部联结&#xff08;等值联结&#xff09; ①WHERE语句 ②ON语句 3.自联结 4.自然联结 5.外部联结 三、组合查询 1.什么是组合查询 2.UNION规则 *本节涉及概念来源于图灵程序设计丛书&a…

成功推出全新生成式AI的四大原则

生成式AI有望从根本上打开一扇新世界机遇的大门&#xff0c;以满足各行各业的客户需求。从提供个性化回复的对话式聊天机器人&#xff0c;到各种应用的代码&#xff0c;再到营销传播的目标内容&#xff0c;生成式AI正在彻底改变企业的运作方式。为竞相提供卓越的客户体验&#…

jupyter lab 自动补全

命令行执行&#xff1a; pip install jupyter-lsp pip install python-lsp-server[all] jupyter lab直接搜索&#xff0c;并安装&#xff0c;重启后生效

使用`scipy.stats.wasserstein_distance`来计算两个一维分布之间的Earth Mover‘s Distance (EMD)距离

在Python中&#xff0c;计算Earth Mover’s Distance (EMD)通常使用scipy库中的scipy.stats.wasserstein_distance函数&#xff0c;该函数计算的是Wasserstein距离&#xff0c;它与EMD非常相似&#xff0c;都是用来衡量两个分布之间的距离。 以下是一个简单的Python程序例子&a…

Web框架开发-BBS(表、登录、注册、文件上传)

一、博客系统表关系 models.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79…

DID分析:上市公司专精特新认定的长期影响(5W+数据)

参照陈金勇&#xff08;2024&#xff09;等人的做法&#xff0c;将上市公司与国家级专精特新小巨人、省级专精特新小巨人、国家级专精特新中小企业、省级专精特新中小企业名单数据进行匹配。包含4类认定标准和年份&#xff0c;并利用四类认定标准分别构建了四类多期DID 一、数据…

进程、线程、协程与虚拟线程(进程相关)

进程、线程、协程与虚拟线程 这一次我们从头&#xff0c;从最大的先开始说&#xff0c;我们从进程开始&#xff0c;因为内容比较多&#xff0c;所以我们分为几个不同的文章来介绍。先从进程&#xff0c;再从线程&#xff0c;最后介绍协程与虚拟线程。 简介 我们以一张操作系…

自动驾驶传感器:惯性导航IMU原理

自动驾驶传感器&#xff1a;惯性导航IMU原理 附赠自动驾驶学习资料和量产经验&#xff1a;链接 组合导航里包含了GNSS卫星导航模块与IMU惯性导航模块&#xff0c;前一篇文章写了GNSS模块&#xff0c;本章写IMU惯导&#xff0c;也是本系列最后一篇文章。 1. 惯性测量单元&…

让 AI 帮你写代码,开发提效神器来了

如今&#xff0c;大量程序员已经习惯在 AI 辅助下进行编程。据调研&#xff0c;AI 编码工具将程序员工作效率提升 50% 以上。 通义灵码是目前国内最受开发者喜爱的 AI 编码助手&#xff0c;可以提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码优化、注释生成、…

回顾皆草木,唯你是青山~

新中式小飞袖连衣裙 每一件衣裳都是时间的礼赞 是炎炎夏日的一抹清新 传统元素与现代时尚设计相结合 面料舒适透气&#xff0c;裙摆飘逸灵动 宛如林间自由洒脱的小仙子~

【Java】IDEA集成开发工具中英文切换

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读小5的系列文章。 这是《Java》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识…

众望所归:FoxPro之后,可视化编程再现新突破,国产力作

许多以前的计算机语言&#xff0c;至今仍然展现出它们强大的生命力。 DOS时代下的FoxPro 然而&#xff0c;曾经风靡一时的FoxPro语言&#xff0c;如今已逐渐淡出人们的视野&#xff0c;令人不禁感慨万分。 每当提及FoxPro&#xff0c;总是有着无尽的话题和回忆。 想当年&am…

65W智能快充—同为科技桌面PDU插座推荐

近10年&#xff0c;移动设备的智能化、功能化已经完全且紧密的融入到我们的基础生活与工作当中。 在常态化的电子设备的应用中&#xff0c;设备的电力续航以及后续的供电充电就尤为重要。 就目前而言&#xff0c;所有消费电子产品中的输入以及充电的接口&#xff0c;usb-c可以…