Summary of chain surface test questions (java implementation)

 The basic implementation of the linked list is written in another blog post http://blog.csdn.net/a447332241/article/details/78947827

Here is a brief summary of some common chain surface test questions

1. The linked list is reversed

2. Print the linked list from end to end

3. Merge ordered linked lists

4. Determine whether the linked list has a ring

5. Find the kth node from the bottom of the linked list


1. The linked list is reversed

We define three pointers to record the node currently traversed, its previous node and the next node, and then traverse sequentially, pointing the pointer of the current node to the previous node.

  public static Node  reverse(Node head)
    {
    	if(head==null||head.next==null)
    		return head;
    	
    	Node cur = head.next;  //当前反转结点结点  
    	Node pre = head;		//前一个结点
    	Node tmp=null;			//中间结点 保存当前结点的下一个结点位置
    	while(cur!=null)
    	{
    		tmp=cur.next; //保存下一个结点
    		
    		cur.next=pre; //反转指向
    		
    		//向后遍历
    		pre=cur;      
    		cur=tmp;											
    	}
    	
    	head.next=null;
    	
    	return pre;
    }

2. Print the linked list from end to beginning

For this kind of reversal of order, we should think of stacks, last in first out . So, this problem either use their own stack, to what the system using the stack, which is recursive . Note that the linked list is empty. The time complexity is O(n)

  Note: Don't think about inverting the singly linked list first, and then traversing the output, this will destroy the structure of the linked list, it is not recommended.


Create a stack yourself
//方法:从尾到头打印单链表
	     public static void reversePrint(Node head) {
	 
	         if (head == null) {
	             return;
	          }
	  
	         Stack<Node> stack = new Stack<Node>();  //新建一个栈
	          Node current = head;
	 
	        //将链表的所有结点压栈
	         while (current != null) {
	             stack.push(current);  //将当前结点压栈
	             current = current.next;
	         }
	
	         //将栈中的结点打印输出即可
	        while (stack.size() > 0) {
	             System.out.println(stack.pop().data);  //出栈操作
	         }
	     }
  Use the system stack, recursively

    //使用系统的栈
	     public static  void reversePrint1(Node head) {
    	 
 
         if (head == null) {
             return;
         }
         reversePrint(head.next);
         System.out.println(head.data);
     }

3. Merge ordered linked lists

Here are two methods 1. Similar to merge sort. Pay special attention to the situation where both linked lists are empty and one of them is empty. Only O (1) space is required. The time complexity is O (max(len1,len2))

	// 两个参数代表的是两个链表的头结点
	public Node mergeLinkList(Node head1, Node head2) {

		if (head1 == null && head2 == null) { // 如果两个链表都为空
			return null;
		}
		if (head1 == null) {
			return head2;
		}
		if (head2 == null) {
			return head1;
		}

		Node head; // 新链表的头结点
		Node current; // current结点指向新链表

		// 一开始,我们让current结点指向head1和head2中较小的数据,得到head结点
		if (head1.data < head2.data) {
			head = head1;
			current = head1;
			head1 = head1.next;
		} else {
			head = head2;
			current = head2;
			head2 = head2.next;
		}

		while (head1 != null && head2 != null) {
			if (head1.data < head2.data) {
				current.next = head1; // 新链表中,current指针的下一个结点对应较小的那个数据
				current = current.next; // current指针下移
				head1 = head1.next;
			} else {
				current.next = head2;
				current = current.next;
				head2 = head2.next;
			}
		}

		// 合并剩余的元素
		if (head1 != null) { // 说明链表2遍历完了,是空的
			current.next = head1;
		}

		if (head2 != null) { // 说明链表1遍历完了,是空的
			current.next = head2;
		}

		return head;
	}
2. Use recursion to achieve
	// 两个参数代表的是两个链表的头结点
	public static Node merage(Node head1, Node head2) {
		if (head1 == null)
			return head2;
		if (head2 == null)
			return head1;

		Node head3 = null;

		if (head1.data < head2.data) {
			head3 = head1;
			head3.next = merage(head1.next, head2);
		} else {
			head3 = head2;
			head3.next = merage(head1, head2.next);
		}
		return head3;//返回合并后链表的头结点

	}
4. Determine whether the linked list has a ring

Idea: To define two pointers, we use two pointers to traverse: the first pointer moves one step at a time, and the second pointer moves two steps at a time. If the first pointer and the second pointer meet, there is a loop.

// 判断单链表是否有环,我们用两个指针去遍历:
	// first指针每次走一步,second指针每次走两步,如果first指针和second指针相遇,说明有环。
	public static boolean hasCycle(Node head) {

		if (head == null) {
			return false;
		}

		Node first = head;
		Node second = head;

		while (second != null) {
			first = first.next; // first指针走一步
			second = second.next.next; // second指针走两步

			if (first == second) { // 一旦两个指针相遇,说明链表是有环的
				return true;
			}
		}

		return false;
	}

5. Find the kth node from the bottom of the linked list

Conventional idea: Assuming that the entire linked list has n nodes, then the kth node from the bottom is the n-k+1th node from the beginning, so we can traverse the linked list twice, and count the list for the first time The number of nodes, the second time we can find the kth node from the bottom. But the interviewer generally only needs to traverse the linked list once, which requires another solution.

We define two pointers. The first pointer starts from the head pointer of the linked list and walks forward k-1 steps, and the second pointer stays still: starting from the k-th step, the second pointer also starts from the head pointer of the linked list. Start the traversal. Since the distance between the two pointers is kept at k-1, when the first (going in front) pointer reaches the end node of the linked list, the second (going behind) pointer is exactly the kth from the bottom. Nodes...

public static Node FindKthtoTail(Node head, int k) {
		if (head == null || k == 0)
			return null;

		Node slow = head;
		Node fast = head;

		for (int i = 0; i < k - 1; i++)
			fast = fast.next;

		while (fast.next != null) {
			fast = fast.next;
			slow = slow.next;
		}
		return slow;

	}
Related topics:

1 Find the middle node of the linked list. If the total number of the linked list is odd, return the middle node; if it is an even number, return any one of the middle two nodes. In order to solve this problem, we can also define two pointers. At the same time, starting from the head node of the linked list, one pointer moves one step at a time, and the other pointer moves two steps at a time. When the faster pointer reaches the end of the linked list, go The slower pointer is right in the middle of the linked list.

       2. Determine whether a linked list is looped, as mentioned above.




Guess you like

Origin blog.csdn.net/a447332241/article/details/78997019