双指针_算法

目录

[0. 双指针](#0. 双指针)

[1. 移动零](#1. 移动零)

[1.1 题目链接](#1.1 题目链接)

[1.2 题目描述](#1.2 题目描述)

[1.3 算法思路](#1.3 算法思路)

[1.4 C++算法代码](#1.4 C++算法代码)

[2. 复写零](#2. 复写零)

[2.1 题目链接](#2.1 题目链接)

[2.2 题目描述](#2.2 题目描述)

[2.3 算法思路](#2.3 算法思路)

[2.4 C++算法代码](#2.4 C++算法代码)

[3. 快乐数](#3. 快乐数)

[3.1 题目链接](#3.1 题目链接)

[3.2 题目描述](#3.2 题目描述)

[3.3 算法思路](#3.3 算法思路)

[3.4 C++算法代码](#3.4 C++算法代码)

[4. 盛最多水的容器](#4. 盛最多水的容器)

[4.1 题目链接](#4.1 题目链接)

[4.2 题目描述](#4.2 题目描述)

[4.3 算法思路](#4.3 算法思路)

[4.4 C++算法代码](#4.4 C++算法代码)

[5. 有效三角形的个数](#5. 有效三角形的个数)

[5.1 题目链接](#5.1 题目链接)

[5.2 题目描述](#5.2 题目描述)

[5.3 算法思路](#5.3 算法思路)

[5.4 C++算法代码](#5.4 C++算法代码)

6.和为s的两个数

[6.1 题目链接](#6.1 题目链接)

[6.2 题目描述](#6.2 题目描述)

[6.3 算法思路](#6.3 算法思路)

[6.4 C++算法代码](#6.4 C++算法代码)

[7. 三数之和](#7. 三数之和)

[7.1 题目链接](#7.1 题目链接)

[7.2 题目描述](#7.2 题目描述)

[7.3 算法思路](#7.3 算法思路)

[7.4 C++算法代码](#7.4 C++算法代码)


0. 双指针

常见的双指针有两种形式,一种是对撞指针,一种是左右指针。

**对撞指针:**一般用于顺序结构中,也称左右指针。

  • 对撞指针从两端向中间移动。一个指针从左端开始,另一个从右端开始,然后逐渐往近。
  • 对撞指针的终止条件一般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出环),也就是:

left == right (两个指针指向同一个位置)

left > right(两个指针错开)

**快慢指针:**又称为龟兔赛跑算法,其基本思想就是使用两个移动速度不同的指针在数组或链表等序列结构上的移动。

这种方法对于处理环形链表或数组非常有用。

其实不单单是环形链表或者数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使用快慢指针的思想。

快慢指针的实现方式有很多种,最常用的一种就是:

  • 在一次循环中,每次让慢的指针向后移动一位,而快的指针往后移动两位,实现一快一慢。

代码链接:

OptimalAlgorithm: OptimalAlgorithm - Gitee.comhttps://gitee.com/Axurea/optimal-algorithm/tree/master/2024_10_7_Algorithm

1. 移动零

1.1 题目链接

283. 移动零 - 力扣(LeetCode)https://leetcode.cn/problems/move-zeroes/description/

1.2 题目描述

1.3 算法思路

1.4 C++算法代码

cpp 复制代码
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]);
    }
};

2. 复写零

2.1 题目链接

1089. 复写零 - 力扣(LeetCode)https://leetcode.cn/problems/duplicate-zeros/description/

2.2 题目描述

2.3 算法思路

2.4 C++算法代码

cpp 复制代码
class Solution {
public:
    void duplicateZeros(vector<int>& arr)
    {
        int cur = 0,dest = -1;
        //找最后一个复写的数
        while(cur < arr.size())
        {
            if(arr[cur] != 0)
                dest++;
            else
                dest +=2;
            if(dest >= arr.size()-1) break;
            cur++;
        }
        //处理一下边界情况
        if(dest == arr.size())
        {
            arr[dest-1] = 0;
            cur--;
            dest-=2;
        }
        //复写操作
        while(cur >= 0)
        {
            if(arr[cur] != 0)
            {
                arr[dest--] = arr[cur--];
            }
            else
            {
                arr[dest--] = arr[cur];
                arr[dest--] = arr[cur--];
                
            }
        }
    }
};

3. 快乐数

3.1 题目链接

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/happy-number/description/

3.2 题目描述

3.3 算法思路

3.4 C++算法代码

cpp 复制代码
class Solution {
public:
    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;
    }
};

4. 盛最多水的容器

4.1 题目链接

11. 盛最多水的容器 - 力扣(LeetCode)https://leetcode.cn/problems/container-with-most-water/description/

4.2 题目描述

4.3 算法思路

4.4 C++算法代码

cpp 复制代码
class Solution {
public:
    int maxArea(vector<int>& height) {
        int left = 0,right = height.size()-1,max = 0,v = 0;
        while(left < right)
        {
            v = (height[left] > height[right] ? height[right] : height[left]) *  (right - left);
            if(v > max) max = v;
            height[left] > height[right] ? right-- : left++;
        }
        return max;
    }
};

5. 有效三角形的个数

5.1 题目链接

611. 有效三角形的个数 - 力扣(LeetCode)https://leetcode.cn/problems/valid-triangle-number/description/

5.2 题目描述

5.3 算法思路

5.4 C++算法代码

cpp 复制代码
class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        //排序优化
        sort(nums.begin(),nums.end());
        //利用双指针解决问题
        int value = 0;
        for(int i = nums.size()-1;i >= 2;i--)
        {
            int left = 0,right = i -1;
            while(left < right)
            {
                if(nums[left] + nums[right] > nums[i])
                {
                    value += right - left;
                    right--;
                }
                else
                {
                    left++;
                }
            }
        }
        return value;
    }
};

6.和为s的两个数

6.1 题目链接

LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode)https://leetcode.cn/problems/he-wei-sde-liang-ge-shu-zi-lcof/description/

6.2 题目描述

6.3 算法思路

6.4 C++算法代码

cpp 复制代码
class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target) {
        int left = 0,right = price.size()-1;
        while(left < right)
        {
            int sum = price[left] + price[right];
            if(sum < target)
                left++;
            else if(sum > target)
                right--;
            else
                return {price[left],price[right]};
        }
        return {-4941, -1};
    }
};

7. 三数之和

7.1 题目链接

15. 三数之和 - 力扣(LeetCode)https://leetcode.cn/problems/3sum/description/

7.2 题目描述

7.3 算法思路

7.4 C++算法代码

cpp 复制代码
class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        sort(nums.begin(),nums.end());
        vector<vector<int>> ret;
        int n = nums.size();
        for(int i = 0;i < n;)
        {
            int x = nums[i];
            for(int j = i + 1;j < n;)
            {
                int begin = j + 1,end = n - 1;
                long long z = (long long)target - nums[i] - nums[j];
                while(begin < end)
                {
                    int sum = nums[begin] + nums[end];
                    if(sum < z) begin++;
                    else if(sum > z) end--;
                    else
                    {
                        ret.push_back({nums[i],nums[j],nums[begin],nums[end]});
                        begin++;
                        while(begin < end && nums[begin] == nums[begin-1]) begin++;
                        end--;
                        while(begin < end && nums[end] == nums[end+1]) end--;
                    }
                }
                j++;
                while(j < n && nums[j] == nums[j-1]) j++;
            }
            i++;
            while(i < n && nums[i] == nums[i-1]) i++;
        }
        return ret;
    }
};
相关推荐
Hera_Yc.H34 分钟前
数据结构之一:复杂度
数据结构
肥猪猪爸2 小时前
使用卡尔曼滤波器估计pybullet中的机器人位置
数据结构·人工智能·python·算法·机器人·卡尔曼滤波·pybullet
linux_carlos2 小时前
环形缓冲区
数据结构
readmancynn2 小时前
二分基本实现
数据结构·算法
Bucai_不才2 小时前
【数据结构】树——链式存储二叉树的基础
数据结构·二叉树
盼海2 小时前
排序算法(四)--快速排序
数据结构·算法·排序算法
一直学习永不止步2 小时前
LeetCode题练习与总结:最长回文串--409
java·数据结构·算法·leetcode·字符串·贪心·哈希表
珹洺3 小时前
C语言数据结构——详细讲解 双链表
c语言·开发语言·网络·数据结构·c++·算法·leetcode
几窗花鸢4 小时前
力扣面试经典 150(下)
数据结构·c++·算法·leetcode
.Cnn4 小时前
用邻接矩阵实现图的深度优先遍历
c语言·数据结构·算法·深度优先·图论