算法DAY04

24.交互链表节点

思路

注意要有两个临时节点,

  • temp1=cur->next
  • temp2=cur->next->next->next

然后按照以下顺序去交换节点
1、cur->next=temp1->next
2、temp1->next->next=temp
3、temp->next=temp2
在这里插入图片描述

code

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* dummyhead=new ListNode(0);
        dummyhead->next=head;
        ListNode* cur=dummyhead;
        while(cur->next!=nullptr&&cur->next->next!=nullptr){
            ListNode* temp=cur->next;
            ListNode* temp1=temp->next->next;//要记录cur后第一个和第三个节点
            cur->next=temp->next;
            cur->next->next=temp;
            temp->next=temp1;
            **cur=cur->next->next;
        }**
        return dummyhead->next;
    }
};

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

思路

要删除一个节点,我们需要cur节点是这个deleteNode的前一个节点。用双指针的方法,left就是deleteNode的前一个节点,当right->next是空指针的时候,就说明left已经到了正确的位置,那么就需要right-left=N.

code

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummyhead=new ListNode(0);
        dummyhead->next=head;
        ListNode* left=dummyhead;
        ListNode* right=dummyhead;
        while(n--){//先向后移动n步right
            right=right->next;
        }
        while(right->next!=nullptr){
            left=left->next;
            right=right->next;
        }
        left->next=left->next->next;
        return dummyhead->next;
    }
};

160.链表相交

思路

让数组尾部对齐

code

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* curA = headA;
        ListNode* curB = headB;
        int lenA = 0, lenB = 0;
        while (curA != NULL) { // 求链表A的长度
            lenA++;
            curA = curA->next;
        }
        while (curB != NULL) { // 求链表B的长度
            lenB++;
            curB = curB->next;
        }
        // 求长度差
        int gap = lenA - lenB;
        // 让curA和curB在同一起点上(末尾位置对齐)
        if(gap<0){
            gap=-gap;
            curA=headB;
            curB=headA;
        }
        else{
            curA = headA;
            curB = headB;
        }
        while (gap--) {
            curA = curA->next;
        }
        // 遍历curA 和 curB,遇到相同则直接返回,都等于NULL也是直接返回NULL
        while (curA != curB) {
            curA = curA->next;
            curB = curB->next;
        }
        return curA;
    }
};

142.环形链表-哈希表/双指针法

哈希表

unordered_set的内部实现了一个 哈希表,通过find()函数来判断,若等于s.end(),也就是找到末尾也没有找到,就插入当前节点

code

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        unordered_set<ListNode*> s;//哈希表用于存放不重复的节点
        ListNode* cur=head;
        while(cur!=NULL){
            if(s.find(cur)!=s.end()){
                return cur;
            }else{
                s.insert(cur);
                cur=cur->next;
            }
        }
        return NULL;
    }
};

快慢指针

在这里插入图片描述

  1. fast、slow指针都从head出发,fast每次走两步,slow每次走一步,step_fast=2*step_slow
    在这里插入图片描述

  2. 如上图,如果slow和fast同一起点出发,当fast和slow相遇时,fast走了两圈,slow走了一圈;

  3. 而这个题目是fast比slow先出发,所以两者相遇时slow还没有走完一圈step_slow=a+b

  4. fast比slow多走一圈step_fast=a+b+(b+c)

  5. 也就是说a+b+(b+c)=2*(a+b)

  6. a=c

  7. 此时让fast从head出发,slow从相遇节点出发,都每次走一步,相遇时就刚好是链表开始入环的节点

code

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;
            if(fast==slow){//第一次相遇
                fast=head;
                while(fast!=slow){
                    slow=slow->next;
                    fast=fast->next;
                }
                return fast;//第二次相遇
            }
        }
        return NULL;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值