7判断环的入口结点8输出倒数第k个

7.判断环的入口结点

在这里插入图片描述
第一次第二次看感觉都无从下手,还是看了题解,主要思路是:
假设前面无环的结点有a个,环有b个结点,则设置快慢结点之后,fast结点一次走两步,slow结点一次走一步。则相遇时fast结点总步长f,slow结点总步长s满足:

f = 2 * s;
f - s = kb;
则s = kb,f=2kb.
我们要找的入口结点在a+kb;因此只要让slow再走a步即可,怎么做呢?只要让第一次相遇后,fast结点从头结点开始一次一步往后走,两者再次相遇的地方就是入口结点

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead) {
        ListNode fast = pHead;
        ListNode slow = pHead;
        int flag =0;
        while(fast!=null && fast.next!=null && fast.next.next!=null){
            fast = fast.next.next;
            slow =slow.next;
            if(fast==slow){
                flag = 1;
                break;
            }
        }
        if(flag==0) return null; //无环
        else{//一定有环
            fast = pHead;
            while(true){
                if(slow==fast) return slow; //一定要先判断!!,否则在a=0的时候就会出错
                fast = fast.next;
                slow = slow.next;
                
            }
        }
        
    }
}

双指针的做法空间复杂度为1,否则用set需要O(N)的空间复杂度,不符合要求

8.输出倒数第k个结点

在这里插入图片描述
让快指针先走k-1步,当快指针到尾部时,慢指针就是倒数第k个。用双指针,空间复杂度为1,时间复杂度为o(N)

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pHead ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    public ListNode FindKthToTail (ListNode pHead, int k) {
        // write code here
        ListNode right = pHead, left = right;
        int count = k-1;
        while(count!=0){//让右边结点先走k-1步
            if(right==null||right.next==null) return null; //说明链表长度比k小
            right = right.next;
            count --;
        }
        while(true){
            if(right.next==null) return left;//当右边结点到尾部时,左边结点就是倒数第k个
            left = left.next;
            right = right.next;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值