代码随想录算法训练营Day04||Leecode24.两两交换链表节点、LLeecode19.删除倒数第N个节点、Leecode.面试02.07链表相交、Leecode142.环形链表||

一、两两交换链表节点

        本题在刚开始的时候没有设置虚拟头结点,且只设置了一个缓存变量,因此在nex指针切换的时候给自己绕晕了,一直找不到解法。同时,循环条件也给他想复杂了,原本想的是定义一个计数器,每逢交换两次就切换节点。但其实只要保证cur->next和cur->next->next两个指针不为空即可。

        cur的更替也是中间的一个错点。本题设置了虚拟头结点,如果把两个节点看成一组的话,就把cur的位置放在这一组的前面,例如0号 1号节点为一组,那么这组的前面就是虚拟头结点,cur初始位置_dummyhead,更替后,23号为一组,那么cur变成1号节点即cur=cur->next->next。

        最后要注意,返回的时候要返回头节点而不是虚拟头结点即返回_dummyhead->next,因为_dummyhead节点要delete掉,所以要提前把有关于_dummyhead的结果保存下来

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
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=cur->next->next->next;
            cur->next=cur->next->next;
            cur->next->next=temp;
            temp->next=temp1;
            cur=cur->next->next;    
         }
         ListNode*result=_dummyhead->next;
         delete _dummyhead;
         return result;


    }
};

二、删除链表倒数N个节点

        一看到题目,第一想法是先把链表反转,然后再进正向删除。 在看完题解后,双指针的算法让我醍醐灌顶。链表倒数的操作可以让两个指针保持一定差值进行同时移动的操作,来达到取倒数的目的。代码的实现思路跟题解一致。

        

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode*_dummyhead=new ListNode(0);
        _dummyhead->next=head;
        ListNode*fastcur=_dummyhead;
        ListNode*lowcur=_dummyhead;
        while(n--){
            fastcur=fastcur->next;
        }
        fastcur=fastcur->next;
        while(fastcur!=nullptr){
            fastcur=fastcur->next;
            lowcur=lowcur->next;
        }
        ListNode*temp=lowcur->next;
        lowcur->next=lowcur->next->next;
        delete temp;
        ListNode*result=_dummyhead->next;
        delete _dummyhead;
        return result;

    }
};

三、链表相交

        对于这个题,我起初有点懵,不知道相交的概念是什么,后来想到了是二者开始存在指针相同的节点就是要返回的节点。但是具体操作我又搞不清楚,也想过用哈希表来做,最后想了一个次优解的办法,只能判断有没有交点不能找到交点是什么。

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

        }
    }
};

        题解的思路是,先把二者的起点搞成一致,然后依次遍历寻找相同指针。其中有个细节是,要把长度长的链表放在A位置,这样后续的代码就可以写成一套方案不用再判断哪个长哪个短了。

        SWAP(A1.A2);函数可以用来交换指针,可以用来交换值,变量名名称不变,变量的内容改变。

        

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode*curA=headA;
        ListNode*curB=headB;
        
        int lenA=0;
        int lenB=0;

        while(curA){
            lenA++;
            curA=curA->next;
        }

        while(curB){
            lenB++;
            curB=curB->next;
        }

        curA=headA;
        curB=headB;
        
        if(lenA<lenB){
            swap(lenA,lenB);
            swap(curA,curB);
        }//到此为止,确立了以A链表为长链表

        int charge=lenA-lenB;
        while(charge--){
            curA=curA->next;

        }

        while(curA!=nullptr){
            if(curA==curB){
                return curA;

            }
            curA=curA->next;
            curB=curB->next;
        }
        return NULL;
  }

};

四、 环形链表

        ?这是啥

        定义快慢指针,若有环,说明快指针能与慢指针重合

        在有环的基础上,已知快慢指针的重合点是相遇点,根据画图已知:此时令一个新的指针从起点出发,让二者相遇即是环的入口

        

        

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode*fast=head;
        ListNode*low=head;

        while(fast!=nullptr&&fast->next!=nullptr){
            fast=fast->next->next;
            low=low->next;
            if(low==fast){
                ListNode*index1=fast;
                ListNode*index2=head;
                while(index1!=index2){
                    index1=index1->next;
                    index2=index2->next;
                }
                return index1;
            }
        }
        return NULL;
    }
};

链表终于完了!!!

如果需要增删改 就引入虚拟头结点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值