代码随想录算法训练营day4

6 阅读2分钟

今日任务: ●  24. 两两交换链表中的节点

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

●  142.环形链表II

24题思考:链表问题最好设置首节点便于记录和返回值,同时两两交换结点时,要注意临时结点的设置,方便进行快速交换,防止不同的next绕晕:

class Solution { public: ListNode* swapPairs(ListNode* head) { ListNode* pre=new ListNode(0); pre->next=head; ListNode* curr=pre; while(curr->next!=nullptr&&curr->next->next!=nullptr){ ListNode* temp=curr->next; curr->next=curr->next->next; temp->next=temp->next->next; curr->next->next=temp; curr=curr->next->next; } ListNode* newhead=pre->next; delete pre; return newhead; } };

19题删除倒数第n个结点,采用双节点可以进行快速定位,当然也可以遍历至链表末尾再进行倒数计数,如果已知链表size的话,则可以更加快速进行计算删除。 需要注意的是,此处双指针的设置,快慢指针所指向的不同位置,慢指针一开始是指向pre的首结点的。 class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode* pre=new ListNode(0,head); ListNode* first=head; ListNode* second=pre; while(n--&&first!=nullptr){ first=first->next; } if(n>0) { ListNode* Newhead=pre->next; delete pre; return Newhead; }

    while(first!=nullptr){
        first=first->next;
        second=second->next;
    } 
    ListNode* delete_node=second->next;
    second->next=delete_node->next;
    delete delete_node;
    ListNode* Newhead=pre->next;
    delete pre;
    return Newhead;
}

};

142.环形链表解题思路,这道题重点需要确定快慢结点之差的具体意义,以及和环入口结点之间的关系,最好通过数学作图可以得到开始结点head,入口结点entry,环长度cir_long 之间的关系。当寻找到环路之后,即切换成满遍历开始寻找入口。

class Solution { public: ListNode *detectCycle(ListNode *head) { //设置快慢两个指针

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

    //检测是否存在循环列表
    while(fast!=nullptr){
       
       slow=slow->next;
        if(fast->next==nullptr){
        return nullptr;
         }
       fast=fast->next->next;

       if(slow==fast){
          //检测入口结点
       ListNode* entry=head;
           while(entry!=slow){
            entry=entry->next;
            slow=slow->next;
             }
        return entry;
        }
      
    }
     return nullptr;
}
    

};