2022/5/30 环形链表 II // 相交链表 // 删除链表的倒数第N个节点

1.环形链表 II

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if(head==null ){              //先判断是否是空表头
            return null;
             }
        ListNode slow=head;
        ListNode fast=head;  
         //使用两个指针,fast 与slow它们起始都位于链表的头部slow                             
         //指针每次 向后移动一个位置,而fast 指针向后移动两个位置
        while(fast!=null){
            slow=slow.next;
            if(fast.next !=null){
            fast=fast.next.next;
            }
        else{
            return null;
        }
        if(fast==slow){       
        //链表中存在环,则fast 指针最终将再次与 slow 指针在环中相遇
        //当发现slow 与 fast 相遇时,我们再额外使用一个指针ptr。
        //起始,它指向链表头部;随后,它和slow 每次向后移动一个位置。最终,它们会在入环点相遇。

            ListNode ptr=head;
            while(ptr !=slow){
                ptr=ptr.next;
                slow=slow.next;
            }return ptr;

             }    
            }
           return null;
        }
        
    }

2.相交链表

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if( headA==null || headB==null){
            return null;
        }
        ListNode pA=headA,pB=headB;
       while(pA!=pB){
           pA=pA==null?headB:pA.next;   //链表A循环结束就循环链表B
           pB=pB==null?headA:pB.next;   //链表A循环结束就循环链表B	
           //(3>2?"A":"B");//满足条件输出A,否则输出B
       }

             return pA;
    }
}

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

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy=new ListNode(0,head);
        //初始化一个空节点,初始赋值为0,并且list的下一个next指针指向head,指针指向为list
        ListNode first=head;
        ListNode second=dummy;
        for(int i=0;i<n;++i){
            first=first.next;
        }
        while(first !=null){
            first=first.next;
            second=second.next;
        }
        second.next=second.next.next;
        ListNode ans=dummy.next;
        return ans;

    }
}

注意问题:

  1. 在调用 next 字段之前,始终检查节点是否为空。
    获取空节点的下一个节点将导致空指针错误。例如,在我们运行 fast = fast.next.next 之前,需要检查 fast 和 fast.next 不为空。
  2. 仔细定义循环的结束条件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值