代码随想录day04

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

题目链接/文章讲解/视频讲解: 代码随想录​​​​​​

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode*dummyhead=new ListNode(0);//创建虚拟头结点
        dummyhead->next=head;
        ListNode*cur=dummyhead;
                ListNode*temp=new ListNode(0);
                ListNode*temp1=new ListNode(0);
        while(cur->next!=NULL&&cur->next->next!=NULL)//注意不能交换顺序,先偶后奇,先判断cur->next!=null才能继续走下去
        {
            temp=cur->next;//先保存第一个节点
            temp1=cur->next->next->next;//保存第三关节点
            cur->next=cur->next->next;//节点1的前线已经断掉,所以需要先保存一下第一个节点
            cur->next->next=temp;//节点2的前线已经断,所以先需要保存节点3,保证不断掉
            temp->next=temp1;
            cur=cur->next->next;//cur往后移两位
        }
        return dummyhead->next;
        delete dummyhead;
    }
};

两个临时节点 (tmptmp1) 的作用是:

  • tmp 保存第一个节点,以防丢失;
  • tmp1 保存后续节点,确保交换后的链表部分能够正确连接。

while(cur->next!=NULL&&cur->next->next!=NULL)

注意不能交换顺序,先偶后奇,先判断cur->next!=null才能继续走下去,否则出现空指针异常

19.删除链表的倒数第N个节点 (快慢指针)

题目链接/文章讲解/视频讲解:代码随想录

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

面试题 02.07. 链表相交

题目链接/文章讲解:代码随想录

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode*cur1=headA;
        ListNode*cur2=headB;
        int size1=0;
        int size2=0;
        //交点不是数值相等,而是指针相等,所以链表应该右对齐
        while(cur1!=NULL)
        {
            cur1=cur1->next;
            size1++;
        }
        while(cur2!=NULL)
        {
            cur2=cur2->next;
            size2++;
        }
        cur1=headA;
        cur2=headB;
        if(size2>size1)
        {
            swap(cur1,cur2);
            swap(size1,size2);
        }//使A链表为最长的那条
        int gap=size1-size2;
        while(gap--)
        {
            cur1=cur1->next;
        }//cur1cur2对齐
        while(cur1!=NULL)
        {
            if(cur1==cur2)
            {
                return cur1;
            }
            cur1=cur1->next;
            cur2=cur2->next;
        }
        return NULL;
    }
};

142.环形链表II

题目链接/文章讲解/视频讲解:代码随想录

追击问题,利用数学公式计算,判断数学关系

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode*fast=head;
        ListNode*slow=head;
        while(fast!=NULL&&fast->next!=NULL)
        {
            slow=slow->next;
            fast=fast->next->next;//快指针相对于慢指针一步一步走,所以不会跳格
            if(slow==fast)//快慢指针相遇
            {
            ListNode*index1=head;
            ListNode*index2=fast;
            while(index1!=index2)
            {
                index1=index1->next;
                index2=index2->next;
            }
            return index1;
            }
        }
        return NULL;
    }
};

注意点1: while(fast!=NULL&&fast->next!=NULL)

快指针为两步两步跳,所以需要判断fast->next!=NULL

2.在推理过程中,大家可能有一个疑问就是:为什么第一次在环中相遇,slow的 步数 是 x+y 而不是 x + 若干环的长度 + y 呢? 3.为什么快指针一定能追上慢指针,不会跳过呢?原因:慢指针一步一步走,快指针两步两步走,快指针相对于慢指针每单位之间只是多走一步,所以一定能追上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值