算法练习 Day4 | leetcode 24. 两两交换链表中的节点,19.删除链表的倒数第N个节点 ,面试题 02.07. 链表相交,142.环形链表II

一、算法题

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

题目链接

class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head==null){
            return head;
        }
        ListNode first=new ListNode();
        first.next=head;
        ListNode cur=first;
        //偶数节点时判断条件是cur.next!=null
        //奇数节点时判断条件是cur.next.next!=null
        //如果用||的话,当cur.next=null后还会继续判断cur.next.next
        //此时会造成空指针异常
        while(cur.next!=null&&cur.next.next!=null){
            ListNode temp=cur.next;
            //cur.next.next.next可能会等于null
            //但是并不影响,最多就是让cur.next.next.next=null
            //然后cur向后移动进入下一次循环时就会出现cur.next.next=null的情况
            //所以会直接退出循环
            ListNode temp1=cur.next.next.next;
            cur.next=cur.next.next;
            cur.next.next=temp;
            cur.next.next.next=temp1;
            cur=cur.next.next;

        }
        return first.next;

    }
}

注意:

  • 最后return的是first.next
  • 因为head可能已经被改变

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

题目链接

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode first=new ListNode(-1);
        first.next=head;
        ListNode fast=first;
        ListNode slow=first;
        n++;
        while(n>0){
            fast=fast.next;
            n--;
        }
        while(fast!=null){
            fast=fast.next;
            slow=slow.next;
        }
        slow.next=slow.next.next;
        return first.next;
    }
}
  • 双指针——快慢指针的经典应用
    • fast先走n+1步,然后fast和slow同时移动,当fast=null时,此时slow移动到了被删除节点的前一个节点的位置
    • 如果走n步,slow会到达被删除节点的位置,但是要进行删除得走到被删除节点的前一个位置

面试题 02.07. 链表相交

题目链接

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode curA=headA;
        ListNode curB=headB;
        int lensA=0;
        int lensB=0;
        while(curA!=null){
            lensA++;
            curA=curA.next;
        }
        while(curB!=null){
            lensB++;
            curB=curB.next;
        }
        curA=headA;
        curB=headB;
        int lens=Math.abs(lensA-lensB);
        if(lensA>lensB){
            while(lens>0){
                curA=curA.next;
                lens--;
            }
            while(curA!=null){
                if(curA==curB){
                    return curA;
                }
                curA=curA.next;
                curB=curB.next;
            }
            return null;
        }
        else{
            while(lens>0){
                curB=curB.next;
                lens--;
            }
            while(curB!=null){
                if(curA==curB){
                    return curB;
                }
                curA=curA.next;
                curB=curB.next;
            }
            return null;
        }
    }
}

注意:

  • 指针存的地址,指针一样,指向一个位置,本题要比较的是结点指针不是值,不要把值和节点的概念混淆起来
  • 节点是一个实例,占用一块空间,值只是它的成员变量,值怎样和节点本身没有任何关系 一个实例只由它的地址唯一确定

142.环形链表II 

题目链接

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if(head==null){
            return null;
        }
        //判断是否有环
        ListNode fast=head;
        ListNode slow=head;
        while(fast.next!=null&&fast.next.next!=null){
            fast=fast.next.next;
            slow=slow.next;
            //找到环的起始节点
            if(fast==slow){
                ListNode index1=head;
                ListNode index2=fast;
                while(index1!=index2){
                    index1=index1.next;
                    index2=index2.next;
                }
                return index1;
            }
        }
        return null;
    }
}
  • 判断是否存在环
    • 快慢指针相遇说明一定有环
  • 环的起始节点

关键点: 

  • x = (n - 1) (y + z) + z
    • 当n=1时,说明x=z,可以推出只要一个节点从相遇节点出发,一个节点从头结点出发,最后一定会在起始处相遇。
    • (n - 1) (y + z)只是说明转了多少圈
  • fast指针一定要跑完一圈才有可能跟slow指针相遇
    • 可以用现实生活中跑圈的思想去理解,同时出发,跑得快的人一定要跑完一圈才能超过跑的慢的人
  • slow指针在第一圈就会被追上
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值