【c++刷题笔记-链表】day04:24. 两两交换链表中的节点 、19.删除链表的倒数第N个节点 、 面试题 02.07. 链表相交 、 142.环形链表II

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

思路:创建哨兵节点,保存待交换的两个节点进行交换

重点:两两相邻交换,不修改节点

交换1-->2->3->4

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* pre=new ListNode(0);
        pre->next=head;
        ListNode* cur=pre;
        while(cur->next!=nullptr&&cur->next->next!=nullptr){
            ListNode* tmp=cur->next;//保存当前第一个要交换的节点
            ListNode* tmp1=cur->next->next->next;//保存两两交换后的第一个要交换的节点
            cur->next=cur->next->next;//1->2
            cur->next->next=tmp;//2->1
            cur->next->next->next=tmp1;//1->3
            cur=cur->next->next;//移动两次找到下一个两两交换的第一个节点
        }
        return pre->next;
    }
};

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

思路:倒数第n个节点就是(单链表的链表长度-n)个节点,引入哨兵节点用快慢指针

重点:快指针需要多走一步,因为删除的是第n个节点,找到第n个节点的前一个节点方便删除

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* node=new ListNode(0);
        node->next=head;
        ListNode* slow=node;
        ListNode* fast=node;
        while(n--&&fast!=nullptr){
            fast=fast->next;//先走n步
        }
        fast=fast->next;//多走一步,下面判断的时候方便找到待删除的前一个节点
        while(fast!=nullptr){
            slow=slow->next;
            fast=fast->next;
        }
        slow->next=slow->next->next;
        return node->next;
    }
};

leetcode 面试题 02.07. 链表相交

思路:先遍历算出两个链表的长度,让长的链表先走它们长度的差值步,再两个链表一起遍历然后比较

重点:链表的数值不能作为判断相同的依据

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* anode=headA;
        ListNode* bnode=headB;
        int a=0,b=0;
        while(anode!=NULL){
            anode=anode->next;
            a++;
        }
        while(bnode!=NULL){
            bnode=bnode->next;
            b++;
        }
        anode=headA;
        bnode=headB;
        if(a>b){
            int t=a-b;
            while(t--){
                anode=anode->next;
            }
        }else{
            int t=b-a;
            while(t--){
                bnode=bnode->next;
            }
        }
        while(anode!=NULL){
            if(anode==bnode){
                return anode;
            }
            anode=anode->next;
            bnode=bnode->next;
        }
        return NULL;
    }
};

leetcode142.环形链表II 

思路:用快慢指针,如果有环就两个指针一定会相交,当两个链表相交的时候让慢指针指向头结点,用快指针指和慢指针比较相同的时候就是环的入口结点

重点:两个链表相交时把慢指针指向头结点再与快指针比较

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* fast=head;
        ListNode* slow=head;
        while(fast!=NULL&&fast->next!=NULL){
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow){
                ListNode* f=fast;
                ListNode* s=head;
                while(f!=s){
                    f=f->next;
                    s=s->next;
                }
                return s;
            }
        }
        return NULL;
    }
};

总结

多使用哨兵结点,这样指针指向会比较清晰,也会方便操作指针。快慢指针技巧,链表有环和求相同的结点的时候可以考虑快慢指针

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值