当前位置: 首页 > article >正文

【优选算法篇】--双指针篇

双指针篇

  • 一、有效三角形的个数
  • 二、快乐数
  • 三、盛最多水的容器
    • 总结: 以上就是本篇内容,欢迎大家在评论区讨论交流。

欢迎来到我的博客园

一、有效三角形的个数

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

在这里插入图片描述


解析:
能否组成三角形,满足任意两边之和大于第三边,大家可能会想到暴力解法。这里提供个最优解法。
对于一组已经排好序的数来说,如果a>=b>=c,则只需b+c>a.
先确定一个最大的数a,再定义left right指针,left指针指向0,right指向最大数的前一位,如果满足左右指针指向的数大于a,那么能组成三角形有效个数就是right-left,这是因为左边第一个数加右边数大于最大数了,中间数肯定比左边第一个数大,那么肯定也满足
在这里插入图片描述

代码篇:

class Solution {
public:
    int triangleNumber(vector<int>& num) {
        //先排序
        sort(num.begin(),num.end());

        int ret=0,n=num.size();
        //系咱固定最大的数,用i来固定
        for(int i=n-1;i>=2;i--)
        {
            //双指针循环
            int left=0,right=i-1;
            while(left<right)
            {
                if(num[left]+num[right]>num[i])
                {
                    ret+=right-left;
                    right--;
                }
                else{
                    left++;
                }
            }
        }
        return ret;
    }
};

二、快乐数

题目;
原题链接

编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:

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

在这里插入图片描述


解析:
这里分两种情况,一种是直接到1,另一种是不会到1(这种会会形成一个环,一直循环下去),如图所示,直接到1的其实也可以看成一个环,只不过换里面全是1,这是我们使用快慢指针的思想,慢指针走一步,快指针走两步,知道相遇即可,并判断相遇位置是否等于1就行。
在这里插入图片描述


代码:

class Solution {
public:
    
    int bitsum(int n)  //返回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]
输出:


解析:
首先我们先理解下题目含义,在第i位置处高度为height[i],最终求最大容量,俩条线之间的最大面积。用暴力枚举会超时,这里使用双指针算法思想。
让左右指针分别从左、右两端进行移动,每移动一次计算他俩之间的面积,最终求面积最大的即可。(移动过程中需注意,谁小谁移动)。


代码:

class Solution {
public:
    int maxArea(vector<int>& height) {
        int left=0,right=height.size()-1,ret=0;
        //左右指针在移动着,结束条件就是他俩相遇
        while(left<right)
        {
            //v计算容积
            int v=min(height[left],height[right])*(right-left);
            ret=max(ret,v);//ret记录最大的
            //谁小谁移动
            if(height[left]<height[right]) left++;
            else    right--;
        }
        return ret;
    }
};

总结:
以上就是本篇内容,欢迎大家在评论区讨论交流。


http://www.kler.cn/a/505114.html

相关文章:

  • C# PDF下载地址转图片(Base64 编码)
  • Ubuntu/centOS 如何安装 OpenGL
  • Web前端------HTML多媒体标签之图片标签
  • 开始使用Panuon开源界面库环境配置并手写VS2019高仿界面
  • 网安——计算机网络基础
  • 【HTML+CSS+JS+VUE】web前端教程-35-字体图标
  • 【AI】【RAG】如何通过WebUI部署与优化RAG问答系统
  • 深度探索:Go 语言日志增强工具 Devslog 的全面解析
  • 配置Kubernetes从节点与集群Calico网络
  • Java算法 数据结构 栈 单调栈实战 模版题 [洛谷-P5788]
  • WOA-CNN-LSTM-Attention、CNN-LSTM-Attention、WOA-CNN-LSTM、CNN-LSTM四模型对比多变量时序预测
  • Android 播放SMB共享视频
  • ImageSharp图形库学习
  • Docker 部署 Typecho
  • 期权懂|场内期权合约行权价格是如何设定制度的?
  • java进行pdf文件压缩
  • 03.选择排序
  • qml XmlListModel详解
  • SDK调用文心一言如何接入,文心一言API接入教程
  • 检验统计量与p值笔记