AlgorithmDay4

day4

24两两交换链表节点

两两交换 返回交换后的头节点

想到递归 迭代 递归的空间一般是on 迭代是o1(不额外)

image-20240406205934264

递归的思想:我最终还是要的是从第二个节点开始

所以第二个是newhead

递归节点自然成了swappair(newhead->next)

注意先让head指向递归节点,再让newhead指向head

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(!head || !head->next) {
            return head;
        }//终止条件
        ListNode* newhead = head->next;
        head->next = swapPairs(newhead->next);
        newhead->next = head;
        return newhead;
    }
};

迭代:

image-20240406213744083

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* dummy = new ListNode(0); 
        dummy->next = head; 
        ListNode* cur = dummy;

        while(cur->next != nullptr && cur->next->next != nullptr) {
            ListNode* first = cur->next;
            ListNode* second = cur->next->next;
            // 节点交换
            cur->next = second;
            first->next = second->next;
            second->next = first;
            cur = second->next; 
        }
        head=dummy->next;
        delete dummy;
        return head;
    }
};

迭代的思想:虚节点 第一节点 第二节点

三次改换next操作,循环动起来全靠虚节点的:

下一个和下下一个不是nullptr以及cur指向下下下一个

(重要的是不动head 免得被绕晕)

19删除倒数第n节点

题目:链表倒数第n个给他删了

思路:删除肯定需要知道前一个节点,用于改next指向

找到倒数第n个?快慢指针:

快的先跑n+1,快慢一起跑,他们必定相距n

直到快等于nullptr,慢就是倒数第n个前一个,好操作了

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode*dummy=new ListNode(0);
        dummy->next=head;
        ListNode*fast=dummy;
        ListNode*slow=dummy;
        for(int i=0;i<n+1;i++){
            fast=fast->next;
        }
        while(fast!=nullptr){
            slow=slow->next;
            fast=fast->next;
        }
        slow->next=slow->next->next;
        return dummy->next;
    }
};


代码写的很舒服,思路是对的就很快

面试题 链表相交

题目:让长的和短的链表一块比 看到啥时候“指针相等”而不是值相等!!!

指向的是同一个内存地址,那么它们就是相等的。

思路:长的先走到和短同步的位置,再一块对比指针

涉及到链表的length,遍历求解。

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    ListNode *tempA = headA;
    ListNode *tempB = headB;
    int lenA = 0, lenB = 0;
// 计算链表headA的长度
    while (tempA != nullptr) {
        lenA++;
        tempA = tempA->next;
    }
// 计算链表headB的长度
    while (tempB != nullptr) {
        lenB++;
        tempB = tempB->next;
    }
    tempA = headA;
    tempB = headB;
// 让tempA和tempB分别指向两个链表的起始节点
// 并让长链表的指针先向前移动差值步
    if (lenA > lenB) {
        for (int i = 0; i < lenA - lenB; i++) {
            tempA = tempA->next;
        }
    } else {
        for (int i = 0; i < lenB - lenA; i++) {
            tempB = tempB->next;
        }
    }
// 同时移动tempA和tempB,直到它们相遇
    while (tempA != tempB) {
        tempA = tempA->next;
        tempB = tempB->next;
    }
    return tempA; // 返回相交的起始节点,如果没有相交节点返回nullptr
}
};

142环形链表II

输出的是有环的元素的下标

找环的入口下标元素 没有环返回0

思路:快慢双指针,快的一次两步,慢的一次一步,有环会相遇的,相遇之后,再一个finder从头出发,慢也出发,finder遇到slow直接返回下标

为什么有环,快慢指针会相遇?

答案:想象在操场跑步吧,秒了

为什么finder和slow相遇在环的开头?

image-20240406233957749

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode*slow=head;
        ListNode*fast=head;
        ListNode*finder=head;
while(fast&&fast->next){
            fast=fast->next->next;
            slow=slow->next;
            if(slow==fast){
             while(finder!=slow){
                finder=finder->next;
                slow=slow->next;
            }
            return finder;
            }
            }
            return nullptr;
           
        }
};
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值