代码随想录day4|24. 两两交换链表中的节点,19. 删除链表的倒数第 N 个结点,160. 相交链表, 142.环形链表II

6 篇文章 0 订阅

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

题目链接:24. 两两交换链表中的节点
注意事项:

  • 注意结点在变更时,到底需要保存几个结点的地址、
  • 在第一次提交代码时,忘记设置中间变量temp1导致超时
/**
 * 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 * nhead = new ListNode(0, head); //设置虚拟头结点
        ListNode * cur = nhead;
        while( cur->next != nullptr && cur->next->next != nullptr){ //注意两个条件不能颠倒
            ListNode * temp = cur->next; //保存第0个结点
            ListNode * temp1 = cur->next->next->next; //保存第2个位置的结点地址
            
            cur->next = cur->next->next;
            cur->next->next = temp;
            cur->next->next->next = temp1;  //将后续结点接到第1位置后
            cur = cur->next->next; //从第2个位置结点前一个结点第1结点开始下次循环
        }
        head = nhead->next;
        delete nhead;
        return head;
    }
};

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

题目链接:19. 删除链表的倒数第 N 个结点
注意事项:

  • 指针移动时需要注意到底需要找到的是哪个位置,本题目是删除,需要找到待删除的头一个结点
  • 移动过程可以分成两个循环,也可以在一个循环搞定,如下
/**
 * 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* removeNthFromEnd(ListNode* head, int n) {
        ListNode * nhead = new ListNode(0, head);
        ListNode * cur1 = nhead;	//先行移动的指针
        ListNode * cur2 = nhead;	//后移动的指针
        while(cur1->next != nullptr){
            if(n <= 0){
                cur2 = cur2->next;	//在cur1还未到达指定位置时,cur1还不需移动
            }
            cur1 = cur1->next;
            n--;
        }

        ListNode * temp = cur2->next->next;
        delete cur2->next;
        cur2->next = temp;
        
        head = nhead->next;
        delete nhead;
        return head;
    }
};

160. 相交链表

题目链接:160. 相交链表
注意事项:

  • 理解解题思路,之前从来没有接触这个想法
  • 每次循环的判断条件是cur != nullptr,而不是cur->next != nullptr,因为需要明确的是当前指针的存在性
  • 注意相交的链表节点判断的是地址相同与否,而不是结点的val值
  • 再次使用cur进行对链表的遍历时,需要再次将cur初始化成头结点地址
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        int lenA = 0, lenB = 0;
        ListNode * curA = headA;
        ListNode * curB = headB;
        while(curA != nullptr){
            lenA++;
            curA = curA->next;
        }

        while(curB != nullptr){
            lenB++;
            curB = curB->next;
        }

        if(lenA < lenB){	//将A链表修改为长度最长的链表
            curA = headB;
            curB = headA;
            swap(lenA, lenB);
        }else{
            curA = headA;
            curB = headB;
        }

        int count = lenA - lenB;

        while(count--){	//将两个链表对齐后向下共同遍历
            curA = curA->next;
        }
        while(curA != nullptr){
            if(curB == curA){	//如果地址相同,返回当前的地址
                return curA;
            }
            curB = curB->next;
            curA = curA->next;
        }
        return nullptr;
    }
};

142.环形链表II

题目链接:142.环形链表II
注意事项:

  • 理解思路,关键点是找到相交结点后,再次从头结点和相交结点向下遍历,再次相会的结点为链表的环形入口结点
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode * slow = head;
        ListNode * fast = head;

        while(fast != nullptr && fast->next != nullptr){
            slow = slow->next;
            fast = fast->next->next;
            if(slow == fast){
                ListNode * cur1 = slow;
                ListNode * cur2 = head;
                while(cur1 != nullptr){
                    if(cur1 == cur2){
                        return cur1;
                    }
                    cur1 = cur1->next;
                    cur2 = cur2->next;
                }
            }
        }
        return nullptr;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值