C++优选算法 | 双指针篇(一)

283.移动零

题目描述

输入输出示例

解题

算法思路

  • 创建cur、dest两个指针,从 [ 0,dest ) 为处理好的数组,dest指向最近的一个0,[ dest,cur ]为0,( cur,nums.size()-1 ]为未处理的数组
  • 依次挪动两个指针直到cur指向数组末尾

C++代码演示

cpp 复制代码
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int cur=0;
        int dest=-1;
        while(cur!=nums.size())    //遍历数组
        {
            if(nums[cur]==0)    //为0则继续向后走
            {
                cur++;
            }
            else    //不为0则交换dest下一个元素(为0)
            {
                swap(nums[++dest],nums[cur++]);
            }
        }
    }
};

1089.复写零

题目描述

输入输出示例

解题

算法思路

  • 创建两个指针,先从前往后遍历,找到输出时最后一个数字的位置
  • 根据指针位置从后往前遍历,填入对应值

C++代码演示

cpp 复制代码
class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int cur=0;
        int dest=-1;
        //从前往后走
        //通过循环找到输出是数组最一个值的位置cur
        while(cur<arr.size())
        {
            if(arr[cur]!=0)
            {
                dest++;
            }else
            {
                dest+=2;
            }

            if(dest>=arr.size()-1)    //表明当前的cur已经要输出数组的最后一个值了
            {
                break;
            }
            cur++;
        }

        //处理边界情况,如果cur为0的话,dest可能会超出下标范围[0,arr.size()-1]到n
        //这样的话最后一个值应为为0
        if(dest==arr.size())
        {
            arr[arr.size()-1]=0;
            cur--;
            dest-=2;    //到arr.size()-2位置
        }

        //从后往前走
        //改变数组
        while(cur>=0)
        {
            if(arr[cur]!=0)
            {
                arr[dest]=arr[cur];
                dest--;
                cur--;
            }else
            {
                arr[dest]=arr[dest-1]=0;
                dest-=2;
                cur--;
            }
        }
    }
};

202.快乐数

题目描述

输入输出示例

解题

算法思路

  • 因为走很多步之后必定会陷入一个循环当中,1的循环为1,2->4->16->37->58->89->145->42->20->4,所以必定有一个环
  • 创建两个指针,慢指针每次算一次,快指针每次算两次,必定会相遇,查看相遇时的值是否相等就可以了

C++代码演示

cpp 复制代码
class Solution {
public:
    int Sum(int n)  //返回n这个数每一位上的平方和
    {
        int sum=0;
        while(n)
        {
            int last=n%10;  //最后一位的值
            sum+=last*last;
            n/=10;
        }
        return sum;
    }
    bool isHappy(int n) {
        int slow=n; //快慢指针
        int fast=Sum(n);
        while(fast!=slow)
        {
            slow=Sum(slow);     //slow走一步
            fast=Sum(Sum(fast));    //fast走两步
        }
        return fast==1;
    }
};

11.盛最多水的容器

题目描述

输入输出描述

解题

算法思路

  • 创建左右两个指针,让他们往中心移动
  • 因为向中心移动时宽度变小,所以要让容器能盛更多的水,需要让高度变大,所以每次放弃高度较小的那条边

C++代码演示

cpp 复制代码
class Solution {
public:
    int maxArea(vector<int>& height) {
        int left=0;
        int right=height.size()-1;
        int ret=0;
        while(left<right)
        {
            ret=max(ret,min(height[left],height[right])*(right-left));
            if(height[left]<height[right])
            {
                left++;
            }
            else
            {
                right--;
            }
        }
        return ret;
    }
};
相关推荐
byzh_rc2 小时前
[微机原理与系统设计-从入门到入土] 微型计算机基础
开发语言·javascript·ecmascript
编程大师哥2 小时前
Java web
java·开发语言·前端
书中藏着宇宙2 小时前
CornerNet的续篇(数据处理与训练)
开发语言·python
你怎么知道我是队长2 小时前
C语言---预处理器
c语言·开发语言·chrome
JAVA+C语言2 小时前
Java ThreadLocal 的原理
java·开发语言·python
穿小甲的技术笔记2 小时前
C++ static_cast 解析:零成本的类型安全转换
c++
精神小伙就是猛2 小时前
C# Task/ThreadPool async/await对比Golang GMP
开发语言·golang·c#
明洞日记2 小时前
【VTK手册036】网格拓扑简化工具:vtkCleanPolyData 使用指南
c++·图像处理·ai·vtk·图形渲染
wakaka_Yu2 小时前
COLMAP 3.13.0 + CUDA 12.9 + Ubuntu24.04 编译
c++