The “Last man standing” is also called “Josephus problem”. Given a number n people standing in a circle, eliminate every kth one until the last one remain. This problem can be solved with circular linked list. First, we build a circular Linked List by adding n nodes. The index starts from 1 (not 0). Then use two pointers prev and p to keep track previous and current node. A while loop is used to remove every kth node until the last one remained.
The following question is a little twist, find Last man standing and second to last man standing. We declare a variable “left” to check whether there are two left. If there are two left, return the prev’s data which is the second to last. The implementation is in Java, JavaScrit and Python.
Amazon Interview Question (CareerCup):
Last Man Standing: A king gathers all the men in the kingdom who are to be put to death for their crimes, but because of his mercy, he will pardon one. He gathers the men into a circle and gives the sword to one man. The man kills the man to his left, and gives the sword to the man to the dead man’s left. The last man alive is pardoned.
With 5 men, the 3rd is the last man alive.
Write a program that accepts a single parameter: a number N that represents the number of criminals to start with. The program should output the number of the last two men alive.
Example #1: myProgram 5
would output:
5, 3
Example #2: myProgram 7
would output:
3, 7
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
public class LastMenStanding { static class LinkNode { int data; LinkNode next = null; //Constructor, Time O(1), Space O(1) public LinkNode(int value) { this.data = value; } } //Two pointers, Time O(n), Space O(n), n is input number public static int lastMenStanding(int n) { LinkNode head = new LinkNode(1); LinkNode prev = head; for (int i = 2; i <= n; i++) { //build circular linked list, starting from 1 prev.next = new LinkNode(i); prev = prev.next; } prev.next = head; //last node connects to head LinkNode p = head; prev = null; int left = n; //number of nodes left in the list while (left >= 2) { if (left == 2) //second to last System.out.print("Second to last: " + prev.data); for (int i =1; i < 2; i++) { //move every other one prev = p; p = p.next; } prev.next = p.next; //remove the node from the list p = prev.next; left--; } return p.data; } public static void main(String[] args) { int n = 5; System.out.println( "with " + n + " men"); int p = lastMenStanding(n); System.out.println(", last: " + p); n = 7; System.out.println( "\nwith " + n + " men"); p = lastMenStanding(n); System.out.println(", last: " + p); } } |
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
class LinkNode { //Constructor, Time O(1), Space O(1) constructor(value) { this.data = value; this.next = null; } } //Two pointers, Time O(n), Space O(n), n is input number function lastMenStanding(n) { var head = new LinkNode(1); var prev = head; for (let i = 2; i <= n; i++) { //build circular linked list, starting from 1 prev.next = new LinkNode(i); prev = prev.next; } prev.next = head; //last node connects to head var p = head; prev = null; var left = n; //number of nodes left in the list while (left >= 2) { if (left == 2) //second to last console.log("Second to last: " + prev.data); for (let i =1; i < 2; i++) { //move every other one prev = p; p = p.next; } prev.next = p.next; //remove the node from the list p = prev.next; left--; } return p.data; } let n = 5; console.log( "with " + n + " men"); let p = lastMenStanding(n); console.log("last: " + p); n = 7; console.log( "\nwith " + n + " men"); p = lastMenStanding(n); console.log("last: " + p); |
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
class LinkNode : #Constructor, Time O(1), Space O(1) def __init__(self, value): self.data = value self.next = None #Two pointers, Time O(n), Space O(n), n is input number def lastMenStanding(n) : head = LinkNode(1) prev = head for i in range(2, n+1) : #build circular linked list, starting from 1 prev.next = LinkNode(i); prev = prev.next; prev.next = head; #last node connects to head p = head prev = None left = n #number of nodes left in the list while left >= 2: if left == 2: #second to last print("Second to last: " + str(prev.data)) for i in range (1 , 2): #move every other one prev = p p = p.next prev.next = p.next #remove the node from the list p = prev.next left -= 1 return p.data n = 5 print( "with " + str(n) + " men") p = lastMenStanding(n) print("last: " + str(p)) n = 7 print( "\nwith " + str(n) + " men") p = lastMenStanding(n) print("last: " + str(p)) |
Doodle
Output:
With 5 men, the last two standing are:
Second to last: 5, last: 3
With 7 men, the last two standing are:
Second to last: 3, last: 7
O Notation:
Time complexity: O(n)
Space complexity: O(n)
Download LastMenStanding.java
Java Coding Interview Pocket Book (2nd Edition)
Josephus problem solution using recursion