the beginning of the loop

注:出自cracking the coding interview 4ed

Given a circular linked list, implement an algorithm which returns node at the beginning of the loop.

DEFINITION
Circular linked list: A (corrupt) linked list in which a node’s next pointer points to an earlier node, so as to make a loop in the linked list.
EXAMPLE
Input: A -> B -> C -> D -> E -> C [the same C as earlier]

Output: C


If we move two pointers, one with speed 1 and another with speed 2, they will end up meeting if the linked list has a loop. Why? Think about two cars driving on a track—the faster car will always pass the slower one!
The tricky part here is finding the start of the loop. Imagine, as an analogy, two people racing around a track, one running twice as fast as the other. If they start off at the same place, when will they next meet? They will next meet at the start of the next lap.
Now, let’s suppose Fast Runner had a head start of k meters on an n step lap. When will they next meet? They will meet k meters before the start of the next lap. (Why? Fast Runner would have made k + 2(n - k) steps, including its head start, and Slow Runner would have made n - k steps. Both will be k steps before the start of the loop.)
Now, going back to the problem, when Fast Runner (n2) and Slow Runner (n1) are moving around our circular linked list, n2 will have a head start on the loop when n1 enters. Specifically, it will have a head start of k, where k is the number of nodes before the loop. Since n2 has a head start of k nodes, n1 and n2 will meet k nodes before the start of the loop.


So, we now know the following:
1. Head is k nodes from LoopStart (by definition).
2. MeetingPoint for n1 and n2 is k nodes from LoopStart (as shown above).
Thus, if we move n1 back to Head and keep n2 at MeetingPoint, and move them both at the same pace, they will meet at LoopStart.

                                                  

LinkedListNode FindBeginning(LinkedListNode head) {
 LinkedListNode n1 = head;
 LinkedListNode n2 = head;

 // Find meeting point
 while (n2.next != null) {
 n1 = n1.next;
 n2 = n2.next.next;
 if (n1 == n2) {
 break;
 }
 }

 // Error check - there is no meeting point, and therefore no loop
 if (n2.next == null) {
 return null;
 }

 /* Move n1 to Head. Keep n2 at Meeting Point. Each are k steps
 /* from the Loop Start. If they move at the same pace, they must
 * meet at Loop Start. */
 n1 = head;
 while (n1 != n2) {
 n1 = n1.next;
 n2 = n2.next;
 }
 // Now n2 points to the start of the loop.
 return n2;
29 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Here's an example implementation of the main method that fulfills the requirement you described: ```java import java.util.Scanner; public class CLI { public static void main(String[] args) { Library library = new Library(); Scanner scanner = new Scanner(System.in); while (true) { System.out.println("Choose an action:"); System.out.println("1. Print all books"); System.out.println("2. Borrow a book"); System.out.println("3. Check number of books borrowed by a user"); int choice = scanner.nextInt(); scanner.nextLine(); // consume the newline character switch (choice) { case 1: library.printAllBooks(); break; case 2: System.out.println("Enter the name of the book to borrow:"); String bookName = scanner.nextLine(); System.out.println("Enter your name:"); String userName = scanner.nextLine(); try { library.borrowBook(bookName, userName); System.out.println("Book successfully borrowed!"); } catch (BookNotAvailableException e) { System.out.println("Sorry, that book is not available."); } catch (UnknownUserException e) { System.out.println("Sorry, we don't recognize that user."); } break; case 3: System.out.println("Enter the name of the user:"); String checkUserName = scanner.nextLine(); try { int numBorrowed = library.getNumBooksBorrowed(checkUserName); System.out.println(checkUserName + " has borrowed " + numBorrowed + " books."); } catch (UnknownUserException e) { System.out.println("Sorry, we don't recognize that user."); } break; default: System.out.println("Invalid choice."); } } } } ``` Note how we catch the `UnknownUserException` when calling `library.getNumBooksBorrowed()`, print the error message using `e.getMessage()`, and then just continue the loop to print the menu of actions again.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值