(141、876、11)双指针

大家好哇!我是湫湫。

进入正题,最近刷了一些基础题,想通过文章记录自己的学习过程。

本专栏主要加载了一些不同类型的C++题。

非常感谢大家的阅读,如果有不对的地方欢迎指正。


目录

一、快慢指针

题目1(141.环形链表):

题解:

解题:

题目2(876.链表的中间结点):

题解:

解题:

二、左右指针

题目1(11.盛最多水的容器)

题解:

解题:


一、快慢指针

1、两个指针同向而行,按不同的速度或策略移动。

2、常用于检测是否成环,查找链表某些特定节点等。

3、明确指针的初始位置,移动速度/策略,停止条件,仔细处理边界情况。

题目1(141.环形链表):

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环,则返回true。否则,返回false。

题解:

如下图所示,每次fast走两步,slow走一步

如若链表有环,它们就会在链表上某一个节点处相遇----判断链表有环的条件

如若没有环,最后呢fast会指向NULL。

解题:

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; 
    }
};

注:如若存在环,得满足fast和fast->next需要不为空

题目2(876.链表的中间结点):

给你单链表的头结点 head ,请你找出并返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

题解:

如下图所示,此题与上面描述的题类似,主要不同在

快指针指针走完所有结点,此时慢指针正好位于中间结点

解题:

class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        if (!head || !head->next) {
            return head;
        }

        auto fast = head;
        auto slow = head;
        while (fast && fast->next) {
            fast = fast->next->next;
            slow = slow->next;
        }

        return slow;
    }
};

二、左右指针

1、两个指针从两端想向而行,相遇时结束

2、相遇时,可能已经遍历了某个特定部分或者满足了某个条件

3、根据题目条件确定哪个指针走

题目1(11.盛最多水的容器)

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:不能倾斜容器。

题解:

根据题意画出以下图形示例

       一般的方法是求解第一个柱子和后面柱子依次构成的面积,直到第一个柱子和后面的柱子都组合完成。然后再用第二个柱子和它后面的柱子组合求解一下面积,以此类推,找到求解中面积最大的,显然此方法可行,但费时费力。

就很有必要用左右指针的思想

water=min(height[1],height[8])*(8-1)

->w(i,j)=min(height[i],heigth[j])*(j-i);i<j

->max(w(i,j))

      在w(i,j)=min(height[i],heigth[j])*(j-i);i<j中,(j-i)在不断减小,min(height[i],heigth[j])不变或者变小,对应的w(i,j)的值也会减小,因此,只有min(height[i],heigth[j])变大,就如下图所示时w(i,j)的值最大,移动的结束条件是当i,j相遇时,就可不用移动。

结论:移动对应柱子比较矮的指针。

解题:

class Solution {
public:
    int maxArea(vector<int>& height) {
        int l = 0, r = height.size() - 1;
        int ans = 0;
        while (l < r) {
            int area = min(height[l], height[r]) * (r - l);
            ans = max(ans, area);
            if (height[l] <= height[r]) {
                ++l;
            }
            else {
                --r;
            }
        }
        return ans;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值