代码随想录算法训练营第四天|24. 两两交换链表中的节点 、19.删除链表的倒数第N个节点 、02.07. 链表相交 、142.环形链表II

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

力扣204

核心在于理清楚如何进行调换,每个步骤是如何执行的。

对某个节点进行操作必须要利用它的上一个节点,因而位于两个交换节点前的cur是重要指针,所有操作都围绕它延伸。

先弄清调换的顺序,如上图,有三个步骤,顺序是这样。为了防止丢失,需要用到两个temp指针。调换完,cur往后移两位。

while的循环条件是cur下面的第一和第二位均不为空,这样才存在继续调换的可能。

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* myHead = new ListNode();
        myHead->next = head;
        ListNode* cur = myHead;
        ListNode* temp1;
        ListNode* temp2;
        while(cur->next!=nullptr&&cur->next->next!=nullptr){
            temp1 = cur->next;
            temp2 = cur->next->next->next;

            cur->next = cur->next->next;//步骤1
            cur->next->next = temp1;//步骤2
            temp1->next = temp2;//步骤3
            
            cur = cur->next->next;//cur往后移两位
        }
        return myHead->next;//返回头结点,也就是虚拟头结点的next
    }
};

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

这道题目利用low和fast的两个指针。

由于要删除的倒数第N个结点,所以采取让fast指针先走n+1步,再让low和fast同时移动的方式。

为什么是先走n+1步呢,因为删除某个节点得从其前一个结点入手,这样low最终才能到达指定位置(倒数第n个结点)的上一个结点,然后执行删除即可。

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* myHead = new ListNode();
        myHead->next = head;
        ListNode* fast = myHead;
        ListNode* low = myHead;
        n++;//删除某个节点,得从其前一个结点入手
        while(n--&&fast){
            fast = fast->next;
        }
        while(fast){          //移动两个指针知道fast到了null。
            fast = fast->next;
            low = low->next;
        }
        //删除low->next
        ListNode* temp = low->next;
        low->next = temp->next;
        delete temp;
        return myHead->next;
    }
};

面试题 02.07. 链表相交

力扣0207

链表相交的特点是:

参考代码随想录

 链表相交的一大特点就是最后几位是一样的,两个链表至少都有这么多位。我们可以让两个链表末位对齐再去比较。如上图,B的第一位是不用考虑的,因为B的长度为6,A的长度为5,我们直接从倒数第五位开始比较即可,直到A的倒数第n(n<=5)位和B的倒数第n位相等时,我们就知道A和B从这个位置开始相交。

具体过程就是:分别计算A和B的长度,为方便统一运算,默认A的长度大于B的长度(若不符合,则调换)。然后移动A的cur指针到A和B长度开始对齐的位置。再利用curA和curB一一比较即可。

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        int lenA = 0;
        int lenB = 0;
        ListNode* curA = headA;
        ListNode* curB = headB;
        while(curA){
            lenA++;
            curA = curA->next;
        }
        while(curB){
            lenB++;
            curB = curB->next;
        }
        curA = headA;
        curB = headB;
        if(lenB>lenA){
            swap(lenB,lenA);
            swap(curB,curA);
        }
        int cha = lenA-lenB;
        while(cha--&&curA){
            curA = curA->next;
        }
        while(curA){
            if(curA==curB){
                return curA;
            }
            curA = curA->next;
            curB = curB->next;
        }
        return NULL;
    }
};

142.环形链表II 

把环形链表讲清楚! 如何判断环形链表?如何找到环形链表的入口? LeetCode:142.环形链表II_哔哩哔哩_bilibili 这道题有点像物理题了(笑)。自己做的时候思路是基本没有的。复习的时候得好好看一遍后理解以下几点:

为什么fast 走两个节点,slow走一个节点,有环的话,一定会在环内相遇呢,而不是永远的错开呢?

如何通过公式计算出入口处节点的特点?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值