补打卡20240113

这几天实验室师哥毕业,事有点多

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

创建虚拟头节点,不断的循环直到链表结束,使用暂存节点保存第一个数据,再把第一个数据插入到第二个数据后,之后更改头节点为暂存节点即可,难度不高。

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* dummyHead = new ListNode(0);
        dummyHead->next = head;
        ListNode* cur = dummyHead;
        while (cur) {
            ListNode* tmp;
            if (cur->next) tmp = cur->next;
            if (tmp->next) {
                cur->next = tmp->next;
                tmp->next = cur->next->next;
                cur->next->next = tmp;
                cur = tmp;
            }
            else return dummyHead->next;
        }
        return dummyHead->next;
    }
};

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

暴力解法先遍历节点数目,再找到待删除节点的前一节点进行删除即可

题目进阶要求只能遍历一次节点,题解的思路很巧妙,双指针结合进链表中,建立虚拟头节点,fast先移动n次,之后fast和slow同时移动直到fast为空,此时slow指向即为待删除节点的前一节点,进行删除即可,记得delete(下述代码没写)

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
       ListNode* dummyHead = new ListNode(0);
       dummyHead->next = head;
       ListNode* fast = dummyHead;
       ListNode* slow = dummyHead;
       while (n && fast) {
           fast = fast->next;
           n--;
       }
       while (fast->next) {
           fast = fast->next;
           slow = slow->next;
       }
       slow->next = slow->next->next;
       return dummyHead->next;
    }
};

面试题 02.07. 链表相交

经典题,两个链表list1,list2,创建两个指针,依次遍历list1和list2,谁先指向null谁就重新指向另一个链表,知道两个指针相遇,此时相遇要么指向相交节点,要么指向null,指向null则代表两个链表没有相交

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* p1 = headA;
        ListNode* p2 = headB;
        while (p1 != p2) {
            if (p1 != NULL) p1 = p1->next;
            else p1 = headB;
            if (p2 != NULL) p2 = p2->next;
            else p2 = headA;
        }
        return p1;
    }
};

142. 环形链表 II

非常好的一道题目,之前做过一遍,还是没什么印象。分别定义 fast 和 slow 指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。fast指针一定先进入环中,如果fast指针和slow指针相遇的话,一定是在环中相遇,这是毋庸置疑的。一旦相遇,slow重新指向头指针,并且slow和fast修改移动速度,二者均每次移动一个节点,直至下次相遇的节点处即为环入口。

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;
            // 快慢指针相遇,此时从head 和 相遇点,同时查找直至相遇
            if (slow == fast) {
                ListNode* index1 = fast;
                ListNode* index2 = head;
                while (index1 != index2) {
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index2; // 返回环的入口
            }
        }
        return NULL;
    }
};

总结:19和142还要重点标记。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值