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

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

题目链接

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

思路

这道题二刷。看到题目的思路是想到双指针法,并且:是需要判断链表节点的个数的(在循环条件中就可以判断节点的个数)

本人题解

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        //这道题二刷。看到题目的思路是想到双指针法,并且:是需要判断链表节点的个数的
        //ListNode *pre = head;
        if (head == NULL) return head;
        ListNode *dummyHead = new ListNode(0);//头指针
        dummyHead->next = head;
        ListNode *cur = dummyHead;//cur应当指向head
        //(即cur->next应该是head节点,则下一轮循环的时候cur->next是第3个节点)
        int count = 0;
        while (cur->next != NULL && cur->next->next != NULL) {
            ListNode *tmp1 = cur->next;//这里是需要判断语句,防止操作空指针的
            ListNode *tmp2 = tmp1->next->next;//tmp2可以是空的,进入下一轮循环就能判断出来
            cur->next = cur->next->next;
            //其实不需要进行下面的if判断,因为这一步后dummyhead->next已经是第2个节点了
            if (count == 0) dummyHead = cur;
            cur->next->next = tmp1;
            cur = tmp1;
            cur->next = tmp2;
            count++;
        }
        return dummyHead->next;
    }
};

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

题目链接

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

思路

这道题也可以用双指针法,两个指针中间间隔的数量正好为输入参数n,然后同步移动直到链表末尾。

本人题解

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        //这道题也可以用双指针法,两个指针中间间隔的数量正好为输入参数n
        ListNode *dummyHead = new ListNode(0);
        dummyHead->next = head;
        //对于删除节点,我们需要保留要删除节点的前一个节点,即删除cur->next
        ListNode *cur = dummyHead;
        ListNode *tail = cur;//tail->next为空即停止
        while (n--) {
            tail = tail->next;
        }
        //注意:本人是先走了n步,因此后面就要用tail->next进行判断
        //但也可以先走n+1步,然后用 tail != NULL 进行判断
        while (tail->next != NULL) {
            cur = cur->next;
            tail = tail->next;
        }
        ListNode *tmp = cur->next;
        cur->next = cur->next->next;
        delete tmp;
        return dummyHead->next;
    }
};

面试题 02.07. 链表相交

题目链接

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

思路

思路是有的,就做的太冗余导致执行超出了时间限制。

本人题解

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        //这个相交的点的物理地址相同,而不只是节点的数值相同
        //第一步要把两个链表的长度计算出来;
        //将长的链表移动n(n表示的是链表的长度差)后两个链表同步移动比较
        int lengthA = 0, lengthB = 0;
        ListNode *headAptr = new ListNode(0);
        headAptr->next = headA;
        ListNode *curA = headAptr;
        ListNode *headBptr = new ListNode(0);
        headBptr->next  = headB;
        ListNode *curB = headBptr;
        while (curA->next != NULL) {
            curA = curA->next;
            lengthA++;
        }
        while (curB->next != NULL) {
            curB = curB->next;
            lengthB++;
        }
        //接下来对两个长度进行比较
        if (lengthA < lengthB) {
            int tmp = lengthA;
            lengthA = lengthB;
            lengthB = tmp;
            curA->next = headB;
            curB->next  = headA;
        }
        else {
            curA->next = headA;
            curB->next = headB;//保证curA是最长的链表
        }
        int n = lengthA - lengthB;
        while (n--) {
            curA = curA->next;//长的先走n步
        }
        while (curA->next != NULL ) {
            if (curA->next == curB->next) return curA->next;
            curA = curA->next;
            curB = curB->next;
        }
        return nullptr;
    }
};
///正确题解如下
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        //这个相交的点的物理地址相同,而不只是节点的数值相同
        //第一步要把两个链表的长度计算出来;
        //将长的链表移动n(n表示的是链表的长度差)后两个链表同步移动比较
        int lengthA = 0, lengthB = 0;
        ListNode *curA = headA;
        ListNode *curB = headB;
        while (curA != NULL) {
            curA = curA->next;
            lengthA++;
        }
        while (curB != NULL) {
            curB = curB->next;
            lengthB++;
        }
        //接下来对两个长度进行比较
        if (lengthA < lengthB) {
            int tmp = lengthA;
            lengthA = lengthB;
            lengthB = tmp;//其实上面3行就是内置swap函数的底层!!
            curA = headB;
            curB  = headA;
        }
        else {
            curA = headA;
            curB = headB;//保证curA是最长的链表
        }
        int n = lengthA - lengthB;
        while (n--) {
            curA = curA->next;//长的先走n步
        }
        while (curA != NULL ) {
            if (curA == curB) return curA;
            curA = curA->next;
            curB = curB->next;
        }
        return nullptr;
    }
};

142.环形链表II

题目链接

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

思路

知道是采用快慢双指针的写法,但是不知道如何写!

本人题解

无 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值