代码随想录D4

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

学习资料

题目链接/文章讲解/视频讲解: 代码随想录

代码 

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head == nullptr || head->next == nullptr) return head;

        ListNode* dummyHead = new ListNode(0);
        dummyHead->next = head;
        ListNode* temp = dummyHead;
        ListNode* store1 = nullptr;
        ListNode* store2 = nullptr;

        while(temp->next != nullptr && temp->next->next != nullptr){
            store1 = temp->next;
            store2 = temp->next->next;

            store1->next = store2->next;
            temp->next = store2;
            store2->next = store1;
            
            temp = store1;
        }
        head = dummyHead->next;
        delete dummyHead;
        return head;
    }
};

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

学习资料

题目链接/文章讲解/视频讲解:代码随想录

 代码

看解析之前自己想的解法,需要先遍历一遍获取长度size后,再根据给定的位置计算需要删除的节点索引Index值,最后删除该节点。

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head == nullptr) return nullptr;

        ListNode* dummyHead = new ListNode(0);
        dummyHead->next = head;
        int size = 0;
        ListNode* temp = dummyHead;

        while(temp->next != nullptr){
            temp = temp->next;
            size++;
        }

        temp = dummyHead;
        int index = size - n;
        while(true){
            if(index < 1 || index > size - 1) break;
            index--;
            temp = temp->next;
        }

        ListNode* store = temp->next;
        if(n == 1){
            temp->next = nullptr;
            delete store;
        }
        else{
            temp->next = temp->next->next;
            delete store;
        }

        head = dummyHead->next;
        delete dummyHead;
        return head;
    }
};

快慢指针可以只遍历一次链表就搞定删除操作,并且发现并不需要单独对删除尾结点进行特殊处理

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head == nullptr) return nullptr;

        ListNode* dummyHead = new ListNode(0);
        dummyHead->next = head;
        ListNode* fast = dummyHead;
        ListNode* slow = dummyHead;

        for(int i = 0; i < n + 1; i++){
            fast = fast->next;
        }

        while(fast != nullptr){
            fast = fast->next;
            slow = slow->next;
        }

        ListNode* store = slow->next;
        slow->next = slow->next->next;
        delete store;

        head = dummyHead->next;
        delete dummyHead;
        return head;
    }
};

 面试题 02.07. 链表相交  

学习资料

题目链接/文章讲解:代码随想录

代码 

以前做过,判定相交两种思路,一是哈希集合,二是看两个链表最后一个节点地址是否一致。此题双指针法可以更简单一点

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(headA == nullptr || headB == nullptr){
            return nullptr;
        }

        ListNode* tempA = headA;
        ListNode* tempB = headB;

        while(tempA != tempB){
            tempA = tempA != nullptr ? tempA->next : headB;
            tempB = tempB != nullptr ? tempB->next : headA;
        }
        
        return tempA;
    }
};

 142.环形链表II 

学习资料

题目链接/文章讲解/视频讲解:代码随想录

代码

先通过哈希集合判定是否有环,再通过快慢指针找到起始入环节点

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(!isCycle(head)) return nullptr;

        ListNode* slow = head;
        ListNode* fast = head;

        do{
            slow = slow->next;
            fast = fast->next->next;
        }
        while(slow != fast);

        fast = head;
        while(slow != fast){
            slow = slow->next;
            fast = fast->next;
        }
        return slow;
        
    }

    bool isCycle(ListNode *head){
        if(head == nullptr || head->next == nullptr){
            return false;
        }

        unordered_set<ListNode*> visited;

        ListNode* temp = head;
        while(temp->next != nullptr){
            if (visited.count(temp)) {
                return true;
            }
            visited.insert(temp);
            temp = temp->next;
        }
        return false;
    }
};

看过解析后发现我自己上面的解法有点幽默了,用哈希的话其实就已经不用快慢指针了,用快慢指针的话其实已经可以判断是否有环了,优化修改一下

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(head == nullptr || head->next == nullptr){
            return nullptr;
        }
        ListNode* slow = head;
        ListNode* fast = head;

        while(fast != nullptr && fast->next != nullptr){
            slow = slow->next;
            fast = fast->next->next;

            if(slow == fast){
                fast = head;
                while(slow != fast){
                slow = slow->next;
                fast = fast->next;
                }
                return slow;
            }
        }
        return nullptr;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值