一道算法题目的思考

最近看到关于环的算法题以为颇有意思,因而思考了一会,如今分几步把解法展现出来.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了.

相关文章
相关标签/搜索