学习笔记--链表8.17

142.环形链表②

在这里插入图片描述
在这里插入图片描述
(一开始没反应过来总是觉得两者总是在环入口处相遇,没有将fast=fast->next)

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
          if (head == NULL || head->next == NULL) {return NULL;}
        ListNode* slow = head;
        ListNode* fast = head;
        while (fast && fast->next)
        {
            fast = fast->next->next;
            slow = slow->next;
            if (fast == slow)
            {
                ListNode* p = head;
                while (p != fast) { p = p->next;fast=fast->next; }                
                return p;
            }
        }       
        return NULL;        
    }

(hash表会更简单以后更新)

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

在这里插入图片描述

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode*p=head,*s=head;
        int len=0,i=0;
        while(p){p=p->next;len++;}
        if(len==n){head=head->next;return head;}//用哑结点的话就不需要判断这个了
        while(i<len-n-1){
            s=s->next;
            i++;
        }
        auto tmp=s->next;
        s->next=s->next->next;
        delete tmp;
        return head;      
    }

方二:一趟扫描的方法,双指针

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

328. 奇偶链表

lass Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        ListNode*odd=head;
        if(head==nullptr||head->next==nullptr)return head;
        ListNode*even=head->next;
        ListNode* headeven=even;
        while(odd->next&&odd->next->next){
            
            odd->next=odd->next->next;
            odd=odd->next;
            even->next=even->next->next;
            even=even->next;;
        }
        odd->next=headeven;
        return head;
    }

234. 回文链表

在这里插入图片描述

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        ListNode*p=head;
        ListNode*q=head;
        int len=0;
        while(p){p=p->next;len++;}
        if(len==1)return true;
        if(len==2){
            if(head->val==head->next->val)return true;
            else return false;
        }
        int index=len/2;
        int i=1;
        while(q&&i<=index){
            q=q->next;
            i++;
        }//这里也可以使用快慢指针,快指针到结尾慢指针刚好到终点
        ListNode*pre=NULL;
        while(q)
        {
            auto tmp=q->next;
            q->next=pre;
            pre=q;
            q=tmp;
        }
        ListNode*p1=head;
        ListNode*p2=pre;
        while(p1&&p2)
        {
            if(p1->val!=p2->val)return false;
            p1=p1->next;
            p2=p2->next;
            
        }
        return true;

    }

这个题解写的清楚一点点

class Solution {
public:
    //题解:快慢指针法,快指针走两步,慢指针走一步,找到链表的中点。然后,翻转后半部分。最后从头、中点开始判断是否相同。
    bool isPalindrome(ListNode* head) {
        if(!head||!head->next)return true;
        ListNode *fast=head,*slow=head,*pre=nullptr;
        //1、找到链表的中点,链表长度奇偶不影响
        while(fast&&fast->next){
            slow=slow->next;
            fast=fast->next->next;
        }
        //2、将slow之后链表进行断开且反转,最后翻转完成之后pre指向反转链表的头节点
        while(slow){
            ListNode *p=slow->next;
            slow->next=pre;
            pre=slow;
            slow=p;
        }
        //3、前后链表进行比较,注意若为奇数链表,后半部分回比前部分多1一个节点,然而我们只比较相同长度的节点值,巧妙地避开这点判断
        while(head&&pre){
            if(head->val!=pre->val)return false;
            head=head->next;
            pre=pre->next;
        }
        return true;
    }
};

21. 合并两个有序链表

在这里插入图片描述

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode*dummy=new ListNode(-1);
        
        ListNode*p=dummy;
        while(l1&&l2){
            if(l1->val<=l2->val)
            {
                p->next=l1;l1=l1->next;p=p->next;
            }
            else {p->next=l2;l2=l2->next;p=p->next;}
        }
        p->next=(l1==nullptr)?l2:l1;
        return dummy->next;
    }

时间复杂度:O(n+m)
空间复杂度:O(1) 。

方二:递归递归递归!!

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if(l1==nullptr) return l2;
        else if(l2==nullptr) return l1;
        else if(l1->val<l2->val){l1->next=mergeTwoLists(l1->next,l2);return l1; }
        else {l2->next=mergeTwoLists(l1,l2->next);return l2;}
        
    }

时间复杂度:O(n+m),其中 n 和 m 分别为两个链表的长度。因为每次调用递归都会去掉 l1 或者 l2 的头节点(直到至少有一个链表为空),函数 mergeTwoList 至多只会递归调用每个节点一次。因此,时间复杂度取决于合并后的链表长度,即 O(n+m)。

空间复杂度:O(n+m),其中 n 和 m 分别为两个链表的长度。递归调用 mergeTwoLists 函数时需要消耗栈空间,栈空间的大小取决于递归调用的深度。结束递归调用时 mergeTwoLists 函数最多调用 n+m 次,因此空间复杂度为O(n+m)。

61. 旋转链表

在这里插入图片描述
还是不知道自己错在哪里,就是一直提示有空指针,十分暴躁以后再调

class Solution {

public:
    ListNode* rotateRight(ListNode* head, int k) {
        ListNode*p=head;
        ListNode*q=head;
        if(head==NULL||head->next==NULL)return head;
        int len=0,i=0;
        while(p){p=p->next;len++;}
        k=k%len;
        if(k==0)return head;
        while(q&&i<len-k){    q=q->next;   }
        ListNode* m=q->next;
        q->next=NULL;
        m->next=head;
        return m;  
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值