4,力扣24. 两两交换链表中的节点,19.删除链表的倒数第N个节点,面试题 02.07. 链表相交,142.环形链表II

文章介绍了如何使用递归和双指针法解决链表问题,包括两两交换链表节点、删除链表的倒数第N个节点、寻找链表相交节点以及环形链表的检测与定位。其中,交换节点采用递归,删除节点使用双指针,查找相交节点提供了哈希集合和双指针两种方法,环形链表II利用快慢指针找到环的入口。
摘要由CSDN通过智能技术生成

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

24. 两两交换链表中的节点 - 力扣(LeetCode)

 代码随想录 (programmercarl.com)

 

 递归官方题解

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if (head == nullptr || head->next == nullptr) {
            return head;
        }
        ListNode* newHead = head->next;
        head->next = swapPairs(newHead->next);
        newHead->next = head;
        return newHead;
    }
};

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

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

双指针法:

 栈:官方解法

 面试题 02.07. 链表相交

面试题 02.07. 链表相交 - 力扣(LeetCode)

方法一官方解法:

哈希集合存储链表节点A,遍历链表B,对遍历到的每个节点,判断该节点是否在哈希集合中,B 中遍历到的第一个在哈希集合中的节点就是两个链表相交的节点

 方法二官方解法:双指针

其中至少有一个链表为空,则两个链表一定不相交
都不为空时,创建两个指针 pA和pB,初始时分别指向两个链表的头节点 headA和headB,将两个指针依次遍历两个链表的每个节点。pA为空,则将指针pA移到链表headB的头节点;如果指针 pB为空,则将指针pB移到链表 headA 的头节点,当指针pA和pB指向同一个节点或者都为空时,返回它们指向的节点或者null。

相交:headAheadB链表相交部分有c个结点,A不相交部分有a个结点,B不相交部分有b个结点,
1.若a=b,两个指针会同时到达两个链表相交结点
2.若a!=b,指针pA移动到链表B的头结点继续移动,指针pB移到链表A的头结点再继续移动,
                 指针pA移动了a+b+c次时,指针pB移动了b+c+a次,同时到达两个链表相交的结点

不相交:headAheadB的长度分别为m、n。
m=n时,两个指针同时到两个链表尾结点,同时成为null,返回null;
m!=n时,pA移动m+n次遍历完AB链表,pB移动n+m次遍历完BA链表,同时为null,返回null。

方法三代码随想录: 代码随想录 (programmercarl.com)

求出两个链表的长度,尾部对齐,A移动到B头部相同位置,同时向后移动,相等时找到交点,不相交循环退出返回空指针。

 

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* curA = headA;
        ListNode* curB = headB;
        int lenA = 0, lenB = 0;
        while (curA != NULL) { // 求链表A的长度
            lenA++;
            curA = curA->next;
        }
        while (curB != NULL) { // 求链表B的长度
            lenB++;
            curB = curB->next;
        }
        curA = headA;
        curB = headB;
        // 让curA为最长链表的头,lenA为其长度
        if (lenB > lenA) {
            swap (lenA, lenB);
            swap (curA, curB);
        }
        // 求长度差
        int gap = lenA - lenB;
        // 让curA和curB在同一起点上(末尾位置对齐)
        while (gap--) {
            curA = curA->next;
        }
        // 遍历curA 和 curB,遇到相同则直接返回
        while (curA != NULL) {
            if (curA == curB) {
                return curA;
            }
            curA = curA->next;
            curB = curB->next;
        }
        return NULL;
    }
};

142.环形链表II

142. 环形链表 II - 力扣(LeetCode)

 方法一代码随想录:代码随想录 (programmercarl.com)

快慢指针:fast指针两步,slow指针一步,对slow来说,fast每次多一步追赶slow,有环则必然相遇,相遇点fast是slow路径的二倍,减去重合路径部分,fast比slow多走了一个(n个)环总长,环总长(n个)与slow到达相遇点的路径长相等,环总长(n个)减去slow在环内走过的路径长与slow减去slow在环内走过的路径长相等,
以相遇点为起始点,指针1走过“环总长(n个)减去slow在环内走过的路径长”(slow第一次到达入口点时,fast在环内走过的长度,也是fast比slow多走的长度)
以头结点为起始点,指针2走过“slow减去slow在环内走过的路径长”,
此时两指针相遇,共同处于环入口位置

方法二:

遍历链表中的每个节点,并记录,一旦遇到了此前遍历过的节点,就可以判定链表中存在环。

 

链表通常需要设置虚拟头结点便于操作,常用双指针法,
还可以用递归、栈、快慢指针等方法解决问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值