算法训练营Day4(链表)

语言

采用的Java语言,一些分析也是用于Java,请注意。

 24. 两两交换链表中的节点 

24. 两两交换链表中的节点 - 力扣(LeetCode)

解题

这道题就是考验链表的基础操作,但是有个语言方面的知识需要去掌握,就是||  |  &&  &的这几个的区别,对于这道题影响还是比较大的,我看好多人在问这个

class Solution {
     public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode(0,head);
        ListNode cur = dummy;
        //dummy 1 2 3 4 5
        while(cur.next!=null&&cur.next.next!=null){
            ListNode temp1 = cur.next;//1
            ListNode temp2 = cur.next.next.next;//3
            cur.next = cur.next.next;//2
            cur.next.next=temp1;
            temp1.next=temp2;
            cur=cur.next.next;
        }
        return dummy.next;
    }
}

这里说一下:

解释为什么用&&和空指针问题

这里为什么用&&:(cur.next!=null && cur.next.next !=null)
1、说明了当奇数节点的时候,比如指向4 后面还有个5的时候,cur.next!=null ,但是cur.next.next==null,第二个不满足条件,就不会在做循环里的反转,若是||的时候,就会把5也给做判断,但实际上是不需要判断的
2、当偶数个节点的时候,4 后面没有5,那么cur.next==null不满足第一个条件,直接就会结束
3、注意&&和&的区别,&&的时候,第一个不成立,下一个就不会执行,所以说,cur.next==null了,cur.next.next就不会执行,不用考虑空指针的问题,所以这两个的位置不能交换

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

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

这到题就注意一下先走n+1步,慢节点就可以倒删除元素的前一个

比如

1   2    3

倒数1个节点

fast=2(1+1) slow=1

fast=3 slow =2

fast=null 循环停止,此时slow=2

slow.next = slow.next.next就把3删掉。

class Solution {
     public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0,head);
        ListNode fast = dummy;
        ListNode slow = dummy;
        //多走1步,slow就会在上一个节点
        n++;
        while(n-->0){
            fast=fast.next;
        }
        while(fast!=null){
            fast=fast.next;
            slow=slow.next;
        }
        slow.next=slow.next.next;
        return dummy.next;
    }
}

 面试题 02.07. 链表相交 

这道题就是让长的链表先移动几个距离,和短的链表保持一样,然后一起移动就可以了,并没有什么难度。

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int lenA=0;
        int lenB=0;
        ListNode curA=headA;
        ListNode curB=headB;
        while(curA!=null){
            lenA++;
            curA=curA.next;
        }
        while(curB!=null){
            lenB++;
            curB=curB.next;
        }
        ListNode shortLen=null;
        ListNode longLen = null;
        if(lenA<lenB){
            shortLen=headA;
            longLen=headB;
        }else {
            shortLen=headB;
            longLen=headA;
        }
        int len= lenA>lenB?lenA-lenB:lenB-lenA;
        while (len-->0){
            longLen=longLen.next;
        }
        while(shortLen!=null&&longLen!=null){
            if(shortLen==longLen){
                return shortLen;
            }
            shortLen=shortLen.next;
            longLen=longLen.next;
        }
        return null;
    }

 142.环形链表II 

142. 环形链表 II - 力扣(LeetCode)

这道题呢,就是判断链表有环和找到入环的位置,主要难理解一个为什么slow指针被追上的时候肯定没到1圈,通俗的一句话就是,你在操场跑步,我是你的二倍速,那么你跑一圈,我肯定跑完两圈了,之间肯定会有交点。

还有就是为什么会相遇,这个更简单了,入环的之后,两者的相对速度是1,相当于走一次,距离就近了一次,肯定会相遇

public class Solution {
     public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while(fast!=null&&fast.next!=null){
            slow = slow.next;
            fast = fast.next.next;
            if(slow==fast){
                ListNode head1 = head;
                while(slow!=head1){
                    head1 = head1.next;
                    slow = slow.next;
                }
                return head1;
            }
        }
        return null;

    }
}

总结(重点!!卡哥遗漏)

链表总结的话,主要就是虚拟头节点使用,然后就是一些边界处理这里一定要注意,需要有自己的总结,比如说这篇文章24题,我强调的&&号的使用在这道题的意义,这个是需要着重理解的。

以及&&号使用之后,需要注意while循环里的条件是否需要注意空指针的问题,比如24题中,

1 2 3 4 

cur是4 ,cur.next为null,那么因为&&,后面是不会再去判断的,

因为&&,前面是否,那么直接结束循环了,因此不会有空指针的问题,但是cur.next.next放前面就会了,这是值得注意的

 1 2 3 4 5

cur是4,cur.next不为null,接着才会处理cur.next.next发现为null,也跳出循环,符合我们的要求,这也是视频中很多人在问| |号行不行,我在这里解释一下!。

另外,对于类似的这样问题,我在Day3也有做阐述,可以去关注,将在文章末尾去做。可能看的时候还没做,我需要时间分析思考,关注即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值