Bloomberg面经准备: Josephus problem

Given a circular single linked list.Write a program that deletes every kth node until only one node is left. 
After kth node is deleted, start the procedure from (k+1)th node. 
e.g.list is 1->2->3->4->5->1 
k=3 
1. You are at 1, delete 3. 
List is: 1->2->4->5->1 
2. You are at 4, delete 1 
List is: 2->4->5->2 
3. You are at 2,delete 5 
List is: 2->4->2 
4. You are at 2, delete 2 
List is: 4 
Return 4. 

How efficient you can do it?

 Solution 1: Math

Let  f(n,k) denote the position of the survivor. After the  kth person is killed, we're left with a circle of  n-1, and we start the next count with the person whose number in the original problem was (k mod n)+1. The position of the survivor in the remaining circle would be f(n-1,k), if we start counting at 1; shifting this to account for the fact that we're starting at (k mod n)+1 yields the recurrence

f(n, k) = ((f(n-1, k) + k - 1) mod n) + 1, 

f(1, k) = 1

这样理解:

新数组len = n-1, 其中1th num在原数组的位置是  (k mod n)+1, 也就是 (1 + (k-1))mod n+ 1

2nd num 在原数组位置是 (2 + (k-1))mod n + 1

3rd num 在原数组位置是 (3 + (k-1))mod n + 1

After the first person (kth from begining) is killed, n-1 persons are left. So we call josephus(n – 1, k) to get the position with n-1 persons. But the position returned by josephus(n – 1, k) will consider the position starting from k%n + 1. So, we must make adjustments to the position returned by josephus(n – 1, k).

Following is simple recursive implementation of the Josephus problem. The implementation simply follows the recursive structure mentioned above.

Time Complexity, O(N), DP

 1 #include <stdio.h>
 2  
 3 int josephus(int n, int k)
 4 {
 5   if (n == 1)
 6     return 1;
 7   else
 8     /* The position returned by josephus(n - 1, k) is adjusted because the
 9        recursive call josephus(n - 1, k) considers the original position 
10        k%n + 1 as position 1 */
11     return (josephus(n - 1, k) + k-1) % n + 1;
12 }
13  
14 // Driver Program to test above function
15 int main()
16 {
17   int n = 14;
18   int k = 2;
19   printf("The chosen place is %d", josephus(n, k));
20   return 0;
21 }

Solution 2: Simulate the process

Singly LinkedList

先扫一遍,确定有环,并且找到head上一跳节点,然后loop直到head.next == head

 1 package bloomberg;
 2 
 3 public class Josephus {
 4     public class ListNode {
 5         ListNode next;
 6         int val;
 7         public ListNode(int val) {
 8             this.val = val;
 9             this.next = null;
10         }
11     }
12     
13     public int survive(ListNode head, int k) {
14         if (head == null) return -1;
15         ListNode prev = head;
16         while (prev!=null && prev.next!=head) {
17             prev = prev.next;
18         }
19         if (prev == null) return -1; //not a loop
20         //now prev is the previous node of head
21         int count = 1;
22         while (head.next != head) {
23             if (count == k) {
24                 prev.next = head.next;
25                 head = head.next;
26                 count = 1;
27             }
28             else {
29                 head = head.next;
30                 prev = prev.next;
31                 count++;
32             }
33         }
34         return head.val;
35     }
36     
37     public static void main(String[] args) {
38         Josephus sol = new Josephus();
39         ListNode node1 = sol.new ListNode(1);
40         ListNode node2 = sol.new ListNode(2);
41         ListNode node3 = sol.new ListNode(3);
42         ListNode node4 = sol.new ListNode(4);
43         ListNode node5 = sol.new ListNode(5);
44         ListNode node6 = sol.new ListNode(6);
45         node1.next = node2;
46         node2.next = node3;
47         node3.next = node4;
48         node4.next = node5;
49         node5.next = node6;
50         node6.next = node1;
51         int res = sol.survive(node1, 2);
52         System.out.println(res);
53     }
54 }

Doubly LinkedList

可以一边loop一边确定是不是有环,while loop结束条件是 head.next != null && head.next != head, 如果出现head.next == null说明无环, 如果

head.next == head说明仅剩一个元素,正常结束

原文地址:https://www.cnblogs.com/EdwardLiu/p/6189007.html