代码随想录算法训练营第4天 | 24. 两两交换链表中的节点 19.删除链表的倒数第N个节点 160 142

#24 耗时1h 自己想+写,链表这块熟练度欠佳,顺序老想不清

过程中几个调整:

1.经常纠结要不要dummy,结果这题还是要(我真有点判断不出什么时候要/不要)

2.有dummy时返回要是dummy->next

3.调while里面那段的顺序调了半天,一定要画图画图画箭头

4.while条件我也想了半天

ListNode* swapPairs(ListNode* head) {
        
        ListNode * dummy = new ListNode (0,head);
        ListNode * curr = dummy;
        ListNode * tmp1, * tmp2;
        if(curr->next==NULL|| curr->next->next==NULL){return head;}
        
        while (curr->next!=NULL && curr->next->next != NULL ){
            
            tmp1=curr->next->next->next;
            tmp2=curr->next->next;

            curr->next->next->next=curr->next;
            curr->next->next=tmp1;
            curr->next= tmp2; 
            
            curr=curr->next->next;
        }
        return dummy->next;

        
    }

这题箭头顺序变化让我联想到 反转链表,又花半个钟去看了眼,发现逻辑比这个简单多了

while里面每次只改 每个方块有关联的一个箭头,并给pre赋值: curr->next = pre,pre=curr这样

那道题需要注意最终head变了,是pre

#19 耗时9min,我现在水平不行但是每次能自己写出来东西还是挺高兴的

ListNode* removeNthFromEnd(ListNode* head, int n) {
        //find the size of ll, O(n)
        //count the front idx of ll O(1)
        //delete, use dummy O(n)
        
        ListNode * curr = head;
        int len=0;
        while(curr!=NULL){
            len++;
            curr=curr->next;
        }

        int idx=len-n;
        cout<<"idx "<<idx<<endl;

        ListNode * dummy = new ListNode (0, head);
        ListNode * tmp;
        curr=dummy;
        while(idx--){
            
            curr=curr->next;
            
        }
        tmp = curr->next;
        curr->next=curr->next->next;
        delete tmp;

        return dummy->next;

        
    }

#160 链表相交

想不出思路看了思路+自己实现 45min

一开始非要自己写个brute force结果超时了,以后别这么做了没意义,还是趁早看思路,开始自己硬想非觉得是要用快慢指针解决双重for loop,正确思路:对齐tail,两个一起遍历,你加1我加1

后面判断长度那里可以更简洁,但我懒得改了不重要

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {

        ListNode *c1, *c2;
        c1= headA;
        c2= headB;
        int lenA=0; int lenB=0;
        while(c1!=NULL){
            lenA++;
            c1=c1->next;
        }
        while(c2!=NULL){
            lenB++;
            c2=c2->next;
        }
        c1= headA;
        c2= headB;

        if(lenA>=lenB){
            int delta=lenA-lenB;
            while(delta--){
                c1=c1->next;
            }
            while(c2!=NULL && c1!=NULL){
                if(c1==c2){
                    return c1;
                }
                c1=c1->next;
                c2=c2->next;
            }
        }
        c1= headA;
        c2= headB;

        if(lenA<lenB){
            int delta=lenB-lenA;
            while(delta--){
                c2=c2->next;
            }
            while(c2!=NULL && c1!=NULL){
                if(c1==c2){
                    return c1;
                }
                c1=c1->next;
                c2=c2->next;
            }
        }
        return NULL;
    }

#142 环形链表ii 非常重要关键的题 看了卡哥视频确实很好,自己下次再不会再去看视频好了

关键:双指针,fast slow在环内相遇(判断有环),相遇点和head再同时重新出发相遇,为环入口

实现起来很简单,不过我现在经常特殊情况考虑不全比如head==nullptr,都是等报错了再去补充

ListNode *detectCycle(ListNode *head) {
        if (head==NULL){return NULL;}
        ListNode * slow = head;
        ListNode * fast = head;
        ListNode * meet;
        while( fast != NULL && fast->next!=NULL){
            slow=slow->next;
            fast=fast->next->next;
            if(slow==fast){
                meet= slow;
                break;
            }
        }
        if(slow!=fast){
            return NULL;
        }
        ListNode *n1=head;
        ListNode *n2=meet;
        while(n1!=n2){
            n1=n1->next;
            n2=n2->next;
        }
        return n1;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值