链表中前后指针法总结

链表中前后指针法总结

本文将持续更新

模型一:交换链表元素

206. 反转链表

1.思路

链表中的前后指针法,通常是为了记录当前元素的前一个元素的,因为单链表是没法去寻找前面的元素的。这样也可以在只遍历一次链表的情况下解决问题。

思路很简单,只要理清楚各个链表元素的链接顺序即可,即如何交换才能让我们拿到所有需要的元素。

2.实现

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* cur=head;
        ListNode* prev=nullptr;
        while(cur)
        {
            ListNode* next=cur->next;
            cur->next=prev;
            prev=cur;
            cur=next;
        }
        return prev;
    }
};

24. 两两交换链表中的节点

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* dummyhead=new ListNode();
        dummyhead->next=head;
        ListNode* cur=dummyhead;
        while(cur->next!=nullptr&&cur->next->next!=nullptr)
        {
            ListNode* next=cur->next;
            ListNode* nnext=next->next;
            ListNode* nnnext=nnext->next;
            cur->next=nnext;
            nnext->next=next;
            next->next=nnnext;
            cur=next;
        }
        return dummyhead->next;
    }
};

模型二:找规定位置

19. 删除链表的倒数第 N 个结点

1.思路

这一类题的前后指针,往往先让快指针向前前进,然后快慢指针一起前进,最终慢指针的位置就是我们需要的位置。

关键在于在题干中分析出来快指针到底走多远,慢指针才开始走。

2.实现

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummyhead=new ListNode();
        dummyhead->next=head;
        ListNode* fast=dummyhead;
        ListNode* slow=dummyhead;
        int count=0;
        while(count<=n)
        {
            fast=fast->next;
            count++;
        }
        while(fast!=nullptr)
        {
            fast=fast->next;
            slow=slow->next;
        }
        ListNode* next=slow->next;
        slow->next=next->next;
        delete next;
        return dummyhead->next;
    }
};

模型三:环形链表

142. 环形链表 II

1.思路

只需要记住三点,找到两个位置,题就可以解了。

  • 快指针每次比慢指针多走1步
  • 快指针会和慢指针在环中的某一个位置相遇
  • 从相遇位置和起始位置以相同的速度同时出发,最终会在环的入口处相遇

2.实现

public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* fast=head;
        ListNode* slow=head;
        while(fast&&fast->next&&slow)
        {
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow)
            {
                break;
            }
        }
        if(fast==nullptr||fast->next==nullptr)
        {
            return nullptr;
        }
        ListNode* res=head;
        while(res!=slow)
        {
            res=res->next;
            slow=slow->next;
        }
        return res;
    }
};

总结

链表中的前后指针法和数组中的前后指针法处理的问题是不同的,注意区分。

#算法#
全部评论

相关推荐

06-25 09:33
厦门大学 Java
程序员饺子:现在日常估计没啥hc了,等到八月多估计就慢慢有了。双九✌🏻不用焦虑的
投递快手等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务