【C++算法】双指针

简介: 【C++算法】双指针

移动零

  • 算法原理

这类题是属于数组划分、数组分开题型

  • 代码步骤:
  1. 使用cur遍历数组
  2. 当cur所指的元素等于0时,cur向后面移动
  3. 当cur所指的元素不等于0时,dest向后面移动,cur所指元素与dest移动后所指的元素交换
  4. 当cur指向最后一个元素的下一个时,结束。
  • 代码展示
class Solution {
public:
    void moveZeroes(vector<int>& nums) 
    {
        int dest = -1;
        for(int cur = 0; cur < nums.size(); ++cur)
        {
            //如果cur所指的元素非0,交换
            if(nums[cur] != 0)
            {
                swap(nums[++dest], nums[cur]);
            }
        }
    }
};

复写零

题目链接:

  • 算法原理

  • 代码步骤:

  • 代码展示
class Solution {
public:
    void duplicateZeros(vector<int>& arr) 
    {
        //寻找复写的最后一个元素
        int cur = 0;
        int dest = -1;
        int n = arr.size();
        //注意arr.sizr()是size_t无符号类型
        //int(-1)比size_t整数大
        while(cur < n)
        {
            if(arr[cur])
            {
                ++dest;
            }
            else
            {
                dest += 2;
            }
            //注意这个判断条件需要在里面实现
            //如果在整个循环结束判断,cur的值无法保证
            if(dest >= n-1) break;
            cur++;
        }
        //特殊情况处理
        if(dest == n)
        {
            arr[n - 1] = 0;
            --cur;
            dest -= 2;
        }
        //进行从右向左的复写操作
        for(; cur >= 0; --cur)
        {
            if(arr[cur])
            {
                arr[dest--] = arr[cur];
            }
            else
            {
                arr[dest--] = 0;
                arr[dest--] = 0;
            }
        }  
    }
};

快乐数

题目链接:

  • 算法原理

  • 代码步骤:

采用快慢双指针的思想:

  1. 定义快慢双指针
  2. 设置一个每个位置平方和的函数
  3. 慢指针每次向后移动一步
  4. 快指针每次向后移动俩步
  5. 判断快慢指针相遇的时候的值是否为1即可
  • 代码展示
class Solution {
public:
    //计算数每个位置上数字的平方和
    int SquareSum(int n)
    {
        int sum =0;
        while(n > 0)
        {
            int num = n % 10;
            sum += num * num;
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n) 
    {
        int slow = n;
        int fast = SquareSum(n);
        while(slow != fast)
        {
            fast = SquareSum(SquareSum(fast));
            slow = SquareSum(slow);
        }
        if(slow == 1)
        {
            return true;
        }
        else 
        {
            return false;
        }
    }
};

盛最多水的容器

题目链接:

  • 算法原理

  • 代码步骤:
  1. 记录初始w最大时的初始容积
  2. left与right二者中较小者向里面移动,寻找比自己大的值
  3. 找到比自己大的值,记录面积,并与之前的面积比较大小
  4. 当left与right相遇的时候,结束
  • 代码展示
class Solution 
{
public:
    int maxArea(vector<int>& height) 
    {
        int left = 0;
        int right = height.size() - 1;
        //寻找边界的最小值
        int min = (height[left] < height[right]) 
        ? height[left] 
        : height[right];
        //起始容积
        int vmax = min * (right - left);
        while(left < right)
        {
            if(height[left] < height[right])
            {
                //记录此时的left
                int num = left;
                while(left < right)
                {
                    //比较看是否有比height[left]大的值
                    ++left;
                    if(height[num] < height[left])
                    {
                        break;
                    }
                }
            }
            else
            {
                //记录此时的left
                int num = right;
                while(left < right)
                {
                    //比较看是否有比height[left]大的值
                    --right;
                    if(height[num] < height[right])
                    {
                        break;
                    }
                }
            }
            min = (height[left] < height[right]) 
            ? height[left] 
            : height[right];
            int v = min * (right - left);
            vmax = (v > vmax) ? v : vmax; 
        }
        return vmax;
    }
};
class Solution {
public:
    int maxArea(vector<int>& height) 
    {
        int left = 0, right = height.size() - 1, vmax = 0;
        while(left < right)
        {
            int v = min(height[left], height[right]) * (right - left);
            vmax = max(vmax, v);
            if(height[left] < height[right]) ++left;
            else --right;
        }
        return vmax;
    }
};

有效三角形个数

题目链接:

  • 算法原理

  • 代码步骤:
  1. 对数组进行排序
  2. 设置三个指针,一个指向最大值,另外俩个形成单调双指针
  3. 当left + right < max时,个数为right-left,right--
  4. 当left + right >= max时,个数为0,left++
  • 代码展示
class Solution {
public:
    int triangleNumber(vector<int>& nums) 
    {
        int n = nums.size();
        //排序升序
        sort(nums.begin(), nums.end());
        int sum = 0;
        //最大值向前移动
        while(n >= 2)//确保right不越界
        {
            int max = nums[n - 1];
            int left = 0, right = n - 2;
            //利用单调性使用双指针
            while(left < right)
            {
                if(nums[left] + nums[right] > max)
                {
                    sum += (right - left);
                    right--;
                }
                else
                {
                    left++;
                }
            }
            --n;
        }
        return sum;
    }
};

三数之和

题目链接:

  • 算法原理

  • 代码步骤:
  1. 排序
  2. 固定一个数min(注意当min > 0的时候,也是可以直接结束的)
  3. 在该数的后面的区间之内,利用单调性使用双指针,快速找到俩个和等于-min的值
  4. 细节1:不漏数据
  5. 细节2:去重操作
  • 代码展示
class Solution 
{
public:
    vector<vector<int>> threeSum(vector<int>& nums) 
    {
        vector<vector<int>> vv;
        //排序
        sort(nums.begin(), nums.end());
        int n = nums.size();
        //固定一个数
        int min = 0;
        for(int min = 0; min < n - 2; ++min)
        {
            //优化
            if(nums[min] > 0) break;
            int left = min + 1, right = n - 1;
            while(left < right)
            {
                if(nums[left] + nums[right] < -nums[min])
                {
                    left++;
                }
                else if(nums[left] + nums[right] > -nums[min])
                {
                    right--;
                }
                else
                {
                    //添加数据
                    vv.push_back({nums[min], nums[left], nums[right]});
                    while(left < right && nums[left] == nums[left + 1])
                    {
                        left++;
                    }
                    while(left < right && nums[right] == nums[right - 1])
                    {
                        right--;
                    }
                    if(left < right)
                    {
                        left++;
                        right--;
                    }
                }
            }
            while(min < n - 2 && nums[min] == nums[min + 1])
            {
                min++;
            }
        }
        return vv;
    }
};

四数之和

题目链接:

  • 算法原理

  • 代码步骤:

  • 代码展示
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 minA = 0; minA < n;)
        {
            long targetA = target - nums[minA];
            //三数之和
            for(int minB = minA + 1; minB < n;)
            {
                long targetB = targetA - nums[minB];
                int left = minB + 1, right = n - 1;
                while(left < right)
                {
                    //利用单调性使用双指针
                    if(nums[left] + nums[right] < targetB)
                    {
                        left++;
                    }
                    else if(nums[left] + nums[right] > targetB)
                    {
                        right--;
                    }
                    else
                    {
                        ret.push_back({nums[minA], nums[minB], nums[left], nums[right]});
                        //left不重
                        while(left + 1 < right && nums[left] == nums[left + 1])
                        {
                            left++;
                        }
                        //right不重
                        while(left < right - 1 && nums[right] == nums[right - 1])
                        {
                            right--;
                        }
                        //不漏
                        if(left < right)
                        {
                            left++;
                            right--;
                        }
                    }
                }
                //minB不重
                while(minB + 1 < n && nums[minB] == nums[minB + 1])
                {
                    minB++;
                }
                ++minB;
            }
            //minA不重
            while(minA + 1 < n && nums[minA] == nums[minA + 1])
            {
                minA++;
            }
            ++minA;
        }
            return ret;
    }
};  


目录
打赏
0
0
0
0
6
分享
相关文章
解读 C++ 助力的局域网监控电脑网络连接算法
本文探讨了使用C++语言实现局域网监控电脑中网络连接监控的算法。通过将局域网的拓扑结构建模为图(Graph)数据结构,每台电脑作为顶点,网络连接作为边,可高效管理与监控动态变化的网络连接。文章展示了基于深度优先搜索(DFS)的连通性检测算法,用于判断两节点间是否存在路径,助力故障排查与流量优化。C++的高效性能结合图算法,为保障网络秩序与信息安全提供了坚实基础,未来可进一步优化以应对无线网络等新挑战。
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
44 15
公司局域网管理中的哈希表查找优化 C++ 算法探究
在数字化办公环境中,公司局域网管理至关重要。哈希表作为一种高效的数据结构,通过哈希函数将关键值(如IP地址、账号)映射到数组索引,实现快速的插入、删除与查找操作。例如,在员工登录验证和设备信息管理中,哈希表能显著提升效率,避免传统线性查找的低效问题。本文以C++为例,展示了哈希表在局域网管理中的具体应用,包括设备MAC地址与IP分配的存储与查询,并探讨了优化哈希函数和扩容策略,确保网络管理高效准确。
员工屏幕监控系统之 C++ 图像差分算法
在现代企业管理中,员工屏幕监控系统至关重要。本文探讨了其中常用的图像差分算法,该算法通过比较相邻两帧图像的像素差异,检测屏幕内容变化,如应用程序切换等。文中提供了C++实现代码,并介绍了其在实时监控、异常行为检测和数据压缩等方面的应用,展示了其实现简单、效率高的特点。
58 15
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
61 12
|
27天前
|
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
在数字化办公时代,公司监控上网软件成为企业管理网络资源和保障信息安全的关键工具。本文深入剖析C++中的链表数据结构及其在该软件中的应用。链表通过节点存储网络访问记录,具备高效插入、删除操作及节省内存的优势,助力企业实时追踪员工上网行为,提升运营效率并降低安全风险。示例代码展示了如何用C++实现链表记录上网行为,并模拟发送至服务器。链表为公司监控上网软件提供了灵活高效的数据管理方式,但实际开发还需考虑安全性、隐私保护等多方面因素。
25 0
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
探秘:基于 C++ 的局域网电脑控制软件自适应指令分发算法
在现代企业信息化架构中,局域网电脑控制软件如同“指挥官”,通过自适应指令分发算法动态调整指令发送节奏与数据量,确保不同性能的终端设备高效运行。基于C++语言,利用套接字实现稳定连接和线程同步管理,结合实时状态反馈,优化指令分发策略,提升整体管控效率,保障网络稳定,助力数字化办公。
75 19
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
70 2
基于红黑树的局域网上网行为控制C++ 算法解析
在当今网络环境中,局域网上网行为控制对企业和学校至关重要。本文探讨了一种基于红黑树数据结构的高效算法,用于管理用户的上网行为,如IP地址、上网时长、访问网站类别和流量使用情况。通过红黑树的自平衡特性,确保了高效的查找、插入和删除操作。文中提供了C++代码示例,展示了如何实现该算法,并强调其在网络管理中的应用价值。
基于哈希表的文件共享平台 C++ 算法实现与分析
在数字化时代,文件共享平台不可或缺。本文探讨哈希表在文件共享中的应用,包括原理、优势及C++实现。哈希表通过键值对快速访问文件元数据(如文件名、大小、位置等),查找时间复杂度为O(1),显著提升查找速度和用户体验。代码示例展示了文件上传和搜索功能,实际应用中需解决哈希冲突、动态扩容和线程安全等问题,以优化性能。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等