剑指offer第二版-23.链表中环的入口节点

作者: ryderchan | 来源:发表于2017-07-14 15:05 被阅读259次

    本系列导航:剑指offer(第二版)java实现导航帖

    面试题23:链表中环的入口节点

    题目要求:
    假设一个链表中包含环,请找出入口节点。若没有环则返回null。

    解题思路:
    当然可以使用遍历。顺序访问,当第二次访问同一个节点时,那么那个节点就是入口节点。不过这种解法需要o(n)的空间。
    能不能把空间降为o(1),时间依旧为o(n)。当然可以。这种解法的思路是:首先申请两个指针,快指针一次前进两步,慢指针一次前进一步,初始化都再链表头部。然后开始移动,如果他们指向了同一个节点,则证明有环,否则没环。当他们指向了同一个节点时,慢指针再次初始化,指向头结点。快慢指针前进步数都改为1,当他们再次指向同一个节点,这个节点就是环的入口节点。不明白的话请先看证明过程链接,然后再看我说的思路总结。

    这3道连续的链表题目,解法上有一定的相似性,都是使用两个指针。碰到链表或者数组的问题,没有好的解法时可以试试这几个常见思路。

    解法 题目 链接
    左右指针 使数组中奇数位于偶数前面/快排 链接
    前后指针 链表中倒数第k个节点 链接
    快慢指针 链表中环的入口节点 链接
    package structure;
    /**
     * Created by ryder on 2017/6/13.
     */
    public class ListNode<T> {
        public T val;
        public ListNode<T> next;
        public ListNode(T val){
            this.val = val;
            this.next = null;
        }
        @Override
        public String toString() {
            StringBuilder ret = new StringBuilder();
            ret.append("[");
            for(ListNode cur = this;;cur=cur.next){
                if(cur==null){
                    ret.deleteCharAt(ret.lastIndexOf(" "));
                    ret.deleteCharAt(ret.lastIndexOf(","));
                    break;
                }
                ret.append(cur.val);
                ret.append(", ");
            }
            ret.append("]");
            return ret.toString();
        }
    }
    
    package chapter3;
    import structure.ListNode;
    /**
     * Created by ryder on 2017/7/14.
     * 链表中倒数第k个节点
     */
    public class P134_KthNodeFromEnd {
        public static ListNode<Integer> findKthToTail(ListNode<Integer> head,int k){
            if(head==null||k<=0)
                return null;
            ListNode<Integer> slow=head,fast=head;
            for(int i=0;i<k;i++){
                //i==k-1,第三个测试例通不过
                if(fast.next!=null || i==k-1)
                    fast = fast.next;
                else
                    return null;
            }
            while(fast!=null){
                slow = slow.next;
                fast = fast.next;
            }
            return slow;
        }
        public static void main(String[] args){
            ListNode<Integer> head = new ListNode<>(1);
            head.next= new ListNode<>(2);
            head.next.next = new ListNode<>(3);
            System.out.println(findKthToTail(head,1).val);
            System.out.println(findKthToTail(head,2).val);
            System.out.println(findKthToTail(head,3).val);
            System.out.println(findKthToTail(head,4));
        }
    }
    

    运行结果

    3
    2
    1
    null
    

    相关文章

      网友评论

        本文标题:剑指offer第二版-23.链表中环的入口节点

        本文链接:https://www.haomeiwen.com/subject/oianhxtx.html