劍指offer第二版-23.鏈表中環的入口節點

本系列導航:劍指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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容