链表篇(下 代码随想录二刷+总结)

链表篇(下 代码随想录二刷+总结)

1.删除链表的倒数第N个结点

leetcode 19
在这里插入图片描述

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode first = head;
        ListNode second = head;
        ListNode virtue = new ListNode(-1,head);
        for(int i=0;i<n;i++){
            second = second.next;
        }
        ListNode pre = virtue;
        while(second!=null){
            second = second.next;
            pre = first;
            first = first.next;
        }
        pre.next = first.next;
        return virtue.next;
    }
}

双指针法:设置first指针指向起始位置,second位置指向顺序第n个位置,然后同时遍历,当second指向空时,first自然指向倒数第n个位置了,这里设置虚拟节点是为了保持一致操作,不设置虚拟节点遇到了head=[1],n=1时就会出错。
针对链表问题,虚拟节点的设置到底影不影响代码,这个要具体分析,个人建议统一设置虚拟节点,出错几率小。

2.链表相交

leetcode 02.07
在这里插入图片描述

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int lengthA=0;
        int lengthB=0;
        ListNode temA = headA;
        ListNode temB = headB;
        while(temA!=null){
            temA = temA.next;
            lengthA++;
        }
        while(temB!=null){
            temB = temB.next;
            lengthB++;
        }
        if(lengthA<lengthB){
            return getNode(headB,headA,lengthB,lengthA);
        }else{
            return getNode(headA,headB,lengthA,lengthB);
        }

    }
    public ListNode getNode(ListNode Long,ListNode shor,int len_long,int len_short){
        for(int i=0;i<(len_long-len_short);i++){
            Long = Long.next;
        }
        while(Long!=null){
        //equals方法默认比较两个对象引用的地址
            if(Long.equals(shor)){
                return Long;
            }
            Long = Long.next;
            shor = shor.next;
        }
        return null;
    }
}

要找相交的点,则一定要以短链表头为起始位置开始找,所以第一步要先将长链表的位置前移到至节点剩余和短链表结点个数一致。然后去遍历比较找到有没有相同结点即可。

3.环形链表Ⅱ

leetcode 142
在这里插入图片描述

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 index1 = slow;
                ListNode index2 = head;
                while(index1!=index2){
                    index1 = index1.next;
                    index2 = index2.next;
                }
                return index1;
            }
        }
        return null;
    }

找环形链表的入环节点,首先要确认这个链表是不是一个环。针对这个问题,设置快慢指针,初始皆指向head,在遍历过程中,fast指针一次跳两个结点,slow跳一个,当slow和fast可以相遇则说明这个链表是个环,循环条件设置fast和fast.next(fast满足slow当然满足,反之不然)。找到环之后要找第一个入环节点,从head处和slow和fast相遇处各自以一个step跳动,相遇处即为入环处。详细推导如下
在这里插入图片描述
哈希表法

public class Solution {
    public ListNode detectCycle(ListNode head) {
        HashSet<ListNode>hs = new HashSet<>();
        ListNode temp = head;
        while(temp!=null){
            if(hs.contains(temp)){
                return temp;
            }
            hs.add(temp);
            temp = temp.next;
        }
        return null;
    }
}

思路简单,费时费力。将遇到的node存入hashset中,若再次遇到则证明其有环,且当前节点为第一个入环节点,直接return。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值