一道算法題目的思考

最近看到關於環的算法題以爲頗有意思,因而思考了一會,如今分幾步把解法展現出來.java

問題1:如何檢測一個單鏈表有環.算法

    設兩個指針,p=head,q=head,從頭結點開始,每次p = p.next  , q= q.next.next ,若是能找到一點p==q就說明這個有環.
this


問題2:一個有環的單鏈表找出環的入口.指針

如圖所示,設置3個變量,根據第一次相遇時,q走的距離是p的兩倍,能夠列出一個方程等式,  2*(a+b) =a+2b+c,最後能夠簡化成  a  =  c.那麼從第一次相遇的焦點到圓環的起始點和從head到圓環的起始點實際上結點數同樣多,這樣就可能夠經過循環判斷來完成.p=head ,  q=第一次相遇點.  while(p!= q) {p=p.next ; q=q.next}  最終找到圓環的起點.code


附上代碼:get

public class FindFrstCircleNode {
	public static void main(String[] args) {
		Node<Integer> head = new Node<Integer>(1);
		Node<Integer> n1 = new Node<Integer>(2);
		Node<Integer> n2 = new Node<Integer>(3);
		Node<Integer> n3 = new Node<Integer>(4);
		Node<Integer> n4 = new Node<Integer>(5);
		Node<Integer> n5 = new Node<Integer>(6);
		Node<Integer> n6 = new Node<Integer>(7);
		Node<Integer> n7 = new Node<Integer>(8);
		Node<Integer> n8 = new Node<Integer>(9);
		Node<Integer> n9 = new Node<Integer>(10);

		head.next = n1;
		n1.next = n2;
		n2.next = n3;
		n3.next = n4;
		n4.next = n5;
		n5.next = n6;
		n6.next = n7;
		n7.next = n8;
		n8.next = n9;
		n9.next = n5;

		FindFrstCircleNode ffcn = new FindFrstCircleNode();
		Node<Integer> p = ffcn.getFirstCircleNode(head);
		System.out.println(p.data);

	}

	public Node<Integer> getFirstCircleNode(Node<Integer> head) {
		Node<Integer> p = head;
		Node<Integer> q = head;
		int count = 0;
		while (count == 0 || p != q) {
			p = p.next;
			q = q.next.next;
			count++;
		}
		p = head;

		while (p != q) {
			p = p.next;
			q = q.next;
		}
		return p;

	}

	static class Node<T> {
		T data;
		Node<T> next;

		public Node() {
			super();
		}
		public Node(T data) {
			super();
			this.data = data;
		}
	}
}

問題3:兩個無環單鏈表有一個結點相交,找出這個交點.class




最爛的解法:變量

循環H1的結點,H1的每一個結點與H2的全部結點對比,時間複雜度是O(n*m)循環

最簡單的解法:遍歷

找到H1的長度m,找到H2的長度n.較長的結點先移動m-n的長度,而後遍歷循環兩個鏈表,結束的條件是p.next=q.next  時間複雜度是O().

最方便的解法:

把H1鏈表結點依次放到HashSet中,而後再把H2鏈表結點依次放入HashSet中,直到沒法放入的時候就找到這個相交的節點了.

最優雅的解法:

把H1最後的結點指向H1的頭部.而後就把問題轉換成問題2了.

相關文章
相關標籤/搜索