双指针算法(超详细版)

希望大家多多关注,有三必回

1.双指针

1.1快慢双指针

快慢双指针常用来解决循环问题,或是查找中间节点

1.1.1循环链表(141. 环形链表 - 力扣(LeetCode)

解题思路:

1.定义快慢指针fast和slow,让fast每次走两步,slow每次走一步

2.如果(slow==fast)相遇则证明有环,如果fast为空,则证明无环

为什么有环一定相遇?

因为我们假设两人赛跑,慢的人相对快的人就是静止的,如果有环,快慢人之间的距离就会不断减小,所以有环一定相遇

cpp 复制代码
//C++版
class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode *slow = head, *fast = head; // 同时从起点出发
        while (fast && fast->next) {
            slow = slow->next; // 慢的走一步
            fast = fast->next->next; // 快的走两步
            if (fast == slow) // 相遇,说明有环
                return true;
        }
        return false; // 访问到了链表末尾,无环
    }
};
cpp 复制代码
//C语言
typedef struct ListNode ListNode;
bool hasCycle(struct ListNode *head) {
    ListNode*fast,*slow;
    fast=slow=head;
    while(fast&&fast->next)
    {
        fast=fast->next->next;
        slow=slow->next;
        if(fast==slow)
        return true;
    }
    return false;
}
1.1.2中间节点(876. 链表的中间结点 - 力扣(LeetCode)

解题思路:

1.定义快慢指针fast和slow,让fast每次走两步,slow每次走一步

2.如果fast为空,则证明有此时的slow即为所求位置

cpp 复制代码
//C++版
class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        ListNode* slow = head;
        ListNode* fast = head;
        while (fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
        }
        return slow;
    }
};
cpp 复制代码
//C语言版
typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) {
    ListNode*fast,*slow;
    fast=slow=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;
}

1.2对撞指针

1.2.1双变化趋势对撞指针(11. 盛最多水的容器 - 力扣(LeetCode)

解题思路:

设两指针 right , left ,分别指向⽔槽板的最左端以及最右端,此时容器的宽度为 right - left 。由于 容器的⾼度由两板中的短板决定,因此可得容积公式 : v = (right - left) * min( height[i], height[j])

注意点:

1.此时的容器宽度只会变小

2.当容器高度发生变化时,容积才会变化

3.不能改变数组的顺序

cpp 复制代码
//C++版本
class Solution {
public:
    int maxArea(vector<int>& height) {
        int right = height.size() - 1, left = 0, ret = 0;
        while (right > left) 
        {
            int v1 = min(height[right], height[left]) * (right - left);
            ret = max(v1, ret);
            if (height[right] < height[left])
                right--;
            else
                left++;
        }
        return ret;
    }
};
cpp 复制代码
//C语言版本
#define MIN(a, b) ((b) < (a) ? (b) : (a))
#define MAX(a, b) ((b) > (a) ? (b) : (a))

int maxArea(int* height, int heightSize) {
    int ans = 0, left = 0, right = heightSize - 1;
    while (left < right) {
        int area = (right - left) * MIN(height[left], height[right]);
        ans = MAX(ans, area);
        height[left] < height[right] ? left++ : right--;
    }
    return ans;
}
1.2.2单变化趋势对撞指针(611. 有效三角形的个数 - 力扣(LeetCode)

如果能构成三⻆形,需要满⾜任意两边之和要⼤于第三边。但是实际上只需让较⼩的两条边 之和⼤于第三边即可。

解题步骤:

1.定义左右指针,即数组下标(lef=0,right=nums.size()-1),来固定三角形种

2.定义变量i来表示中间的边如果nums[i]+nums[left]>nums[right]则可以组成三角形

3.让left不断接近i

cpp 复制代码
class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        sort(nums.begin(),nums.end());//让数组从小到大排列
        int n=nums.size()-1,ret=0;
        for(int right=n;right>=2;right--)//固定right最长边
        {
            int left=0,i=right-1;//固定第二长边i
            while(left<i)//让left不断变化
            {
                if(nums[i]+nums[left]>nums[right])//成立则说明可以组成三角形
                {
                    ret+=i-left;//即[left,i)都可以组成三角形
                    i--;
                }
                else//不成立让最短边边长
                {
                    left++;
                }
            }
        }
        return ret;
    }
};
相关推荐
大山同学几秒前
第三章线性判别函数(二)
线性代数·算法·机器学习
axxy200019 分钟前
leetcode之hot100---240搜索二维矩阵II(C++)
数据结构·算法
黑客Ash31 分钟前
安全算法基础(一)
算法·安全
AI莫大猫1 小时前
(6)YOLOv4算法基本原理以及和YOLOv3 的差异
算法·yolo
taoyong0011 小时前
代码随想录算法训练营第十一天-239.滑动窗口最大值
c++·算法
Uu_05kkq1 小时前
【C语言1】C语言常见概念(总结复习篇)——库函数、ASCII码、转义字符
c语言·数据结构·算法
清梦20203 小时前
经典问题---跳跃游戏II(贪心算法)
算法·游戏·贪心算法
Dream_Snowar3 小时前
速通Python 第四节——函数
开发语言·python·算法
Altair澳汰尔3 小时前
数据分析和AI丨知识图谱,AI革命中数据集成和模型构建的关键推动者
人工智能·算法·机器学习·数据分析·知识图谱
A懿轩A4 小时前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列