Josephus Problem (original) (raw)

There are **n people standing in a circle, numbered from **1 to n. Starting from person **1, counting proceeds in **clockwise direction. In each step, exactly **k-1 people are skipped, and the **k-th person is eliminated from the circle. The counting then resumes from the next person, and the process continues until only one person remains.

Determine the **position of the **last surviving person in the original circle.

**Examples:

**Input: n = 5, k = 2
**Output: 3
**Explanation: Firstly, the person at position 2 is killed, then the person at position 4 is killed, then the person at position 1 is killed. Finally, the person at position 5 is killed. So the person at position 3 survives.

**Input: n = 7, k = 3
**Output: 4
**Explanation: The persons at positions 3, 6, 2, 7, 5, and 1 are killed in order, and the person at position 4 survives.

Table of Content

[Naive Approach - 1] Recursively Removing Elements - O(n^2) Time and O(n) Space

We can store people in an array from1 to n. Since counting is 0-based in the code, we use k-1 instead of k. Starting at index 0, in each step we remove the person at position: (index+(k-1)) % current size.

After removing, the recursive call continues from this new index with the reduced array. This process repeats until only one person remains, who is the survivor.

**Illustration:

C++ `

#include #include using namespace std;

int josephusRec(vector person, int k, int index){

// Base case , when only one person is left
if (person.size() == 1) { ;
    return person[0];
}

// find the index of first person which will die
index = ((index + k) % person.size());

// remove the first person which is going to be killed
person.erase(person.begin() + index);

// recursive call for n-1 persons
return josephusRec(person, k, index);

}

int josephus(int n,int k){

// The index where the person which will die
int index= 0; 

vector<int> person;

// fill the person vector
for (int i = 1; i <= n; i++) {
    person.push_back(i);
}
return josephusRec(person,k,index);

}

int main(){ int n = 7; int k = 3;

// (k-1)th person will be killed
k--;
cout<<josephus(n, k)<<endl;

}

Java

import java.util.ArrayList;

public class GFG {

static int josephusRec(ArrayList<Integer> person, int k, int index) {

    // Base case , when only one person is left
    if (person.size() == 1) { 
        return person.get(0);
    }

    // find the index of first person which will die
    index = (index + k) % person.size();

    // remove the first person which is going to be killed
    person.remove(index);

    // recursive call for n-1 persons
    return josephusRec(person, k, index);
}

static int josephus(int n, int k) {
    
    // The index where the person which will die
    int index = 0;

    ArrayList<Integer> person = new ArrayList<>();

    // fill the person vector
    for (int i = 1; i <= n; i++) {
        person.add(i);
    }
    return josephusRec(person, k, index);
}

public static void main(String[] args) {
    int n = 7;
    int k = 3;

    // (k-1)th person will be killed
    k--;
    System.out.println(josephus(n, k));
}

}

Python

def josephusRec(person, k, index):

# Base case , when only one person is left
if len(person) == 1:
    return person[0]

# find the index of first person which will die
index = (index + k) % len(person)

# remove the first person which is going to be killed
person.pop(index)

# recursive call for n-1 persons
return josephusRec(person, k, index)

def josephus(n, k):

# The index where the person which will die
index = 0

person = []

# fill the person vector
for i in range(1, n + 1):
    person.append(i)

return josephusRec(person, k, index)

if name == "main": n = 7 k = 3

# (k-1)th person will be killed
 k -= 1
 print(josephus(n, k))

C#

using System; using System.Collections.Generic;

class GFG { static int josephusRec(List person, int k, int index) {

    // Base case , when only one person is left
    if (person.Count == 1) {
        return person[0];
    }

    // find the index of first person which will die
    index = (index + k) % person.Count;

    // remove the first person which is going to be killed
    person.RemoveAt(index);

    // recursive call for n-1 persons
    return josephusRec(person, k, index);
}

static int josephus(int n, int k) {
    
    // The index where the person which will die
    int index = 0;

    List<int> person = new List<int>();

    // fill the person vector
    for (int i = 1; i <= n; i++) {
        person.Add(i);
    }

    return josephusRec(person, k, index);
}

static void Main() {
    int n = 7;
    int k = 3;

    // (k-1)th person will be killed
    k--;
    Console.WriteLine(josephus(n, k));
}

}

JavaScript

function josephusRec(person, k, index) {

// Base case , when only one person is left
if (person.length === 1) {
    return person[0];
}

// find the index of first person which will die
index = (index + k) % person.length;

// remove the first person which is going to be killed
person.splice(index, 1);

// recursive call for n-1 persons
return josephusRec(person, k, index);

}

function josephus(n, k) {

// The index where the person which will die
let index = 0;

let person = [];

// fill the person vector
for (let i = 1; i <= n; i++) {
    person.push(i);
}

return josephusRec(person, k, index);

}

// Driver code let n = 7; let k = 3;

// (k-1)th person will be killed k--; console.log(josephus(n, k));

`

[Naive Approach - 2] Using Iterative Simulation - O(n^2) Time and O(n) Space

The idea is to use an array to mark alive people. Initially, all people are alive. Starting from the first person, we count k alive persons in the circle, skipping those already eliminated. When we reach the k-th alive person, we mark them as dead.

After each elimination, counting resumes from the next alive person. We continue this process iteratively, handling the circular nature by wrapping around the array indices, until only one person remains alive.

C++ `

#include #include using namespace std;

int josephus(int n, int k) { k--; int arr[n];

// Makes all the 'n' people alive by
// assigning them value = 1
for (int i = 0; i < n; i++) {
    arr[i] = 1;
}

int cnt = 0, cut = 0,

    // Cut = 0 gives the sword to 1st person.
    num = 1;

// Loop continues till n-1 person dies.
while (cnt < (n - 1)) {

    // Checks next (kth) alive persons.
    while (num <= k) {
        cut++;

        // Checks and resolves overflow
        // of Index.
        cut = cut % n;
        if (arr[cut] == 1) {
            
            // Updates the number of persons
            // alive.
            num++;
        }
    }

    // Refreshes value to 1 for next use.
    num = 1;

    // Kills the person at position of 'cut'
    arr[cut] = 0;

    // Updates the no. of killed persons.
    cnt++;
    cut++;

    // Checks and resolves overflow of Index.
    cut = cut % n;

    // Checks the next alive person the
    // sword is to be given.
    while (arr[cut] == 0) {
        cut++;

        // Checks and resolves overflow
        // of Index.
        cut = cut % n;
    }
}

// Output is the position of the last
// man alive(Index + 1);
return cut + 1;

}

int main(){ int n = 7, k = 3; cout << josephus(n, k); return 0; }

Java

public class GFG {

static int josephus(int n, int k) {
    
    // adjust for 0-based index
    k--; 
    int[] arr = new int[n];

    // Mark all persons as alive (1 = alive)
    for (int i = 0; i < n; i++) {
        arr[i] = 1;
    }

    int cnt = 0, cut = 0, num = 1;

    // Continue until n - 1 people are dead
    while (cnt < (n - 1)) {

        // Find the k-th alive person
        while (num <= k) {
            cut++;
            cut = cut % n; // wrap around
            if (arr[cut] == 1) {
                num++;
            }
        }

        // Reset num for next round
        num = 1;

        // Kill the person at index 'cut'
        arr[cut] = 0;
        cnt++;
        cut = (cut + 1) % n; // move to next

        // Skip dead persons
        while (arr[cut] == 0) {
            cut = (cut + 1) % n;
        }
    }

    // Return position of survivor (1-based index)
    return cut + 1;
}

public static void main(String[] args) {
    int n = 7, k = 3;
    System.out.println(josephus(n, k));
}

}

Python

def josephus(n, k):

k -= 1
arr = [0]*n
for i in range(n):
    
    # Makes all the 'n' people alive by
    # assigning them value = 1
    arr[i] = 1 
cnt = 0
cut = 0

# Cut = 0 gives the sword to 1st person.
num = 1 
while (cnt < (n - 1)):
  
    # Loop continues till n-1 person dies.
    while (num <= k):
      
        # Checks next (kth) alive persons.
        cut += 1
        
        # Checks and resolves overflow
        # of Index.
        cut = cut % n 
        if (arr[cut] == 1):
            
            # Updates the number of persons
            # alive.
            num+=1 
            
    # refreshes value to 1 for next use.
    num = 1 
    
     # Kills the person at position of 'cut'
    arr[cut] = 0
    
    # Updates the no. of killed persons.
    cnt += 1 
    cut += 1
    
    # Checks and resolves overflow of Index.
    cut = cut % n 
    while (arr[cut] == 0):
      
        # Checks the next alive person the
        # sword is to be given.
        cut += 1
        
        # Checks and resolves overflow
        # of Index.
        cut = cut % n 
return cut + 1 

if name == "main": n, k = 7, 3 #map (int, input().splut()) print(josephus(n, k))

C#

using System;

class GFG { static int josephus(int n, int k){

    // adjust for 0-based index
    k--; 
    int[] arr = new int[n];

    // Mark all persons as alive 
    for (int i = 0; i < n; i++){
        arr[i] = 1;
    }

    int cnt = 0, cut = 0, num = 1;

    // Continue until n - 1 people are dead
    while (cnt < n - 1){
        
        // Find the k-th alive person
        while (num <= k){
            cut++;
            cut = cut % n; 
            if (arr[cut] == 1){
                num++;
            }
        }

        // Reset num for next round
        num = 1;

        // Kill the person at index 'cut'
        arr[cut] = 0;
        cnt++;
        
        // move to next
        cut = (cut + 1) % n; 

        // Skip dead persons
        while (arr[cut] == 0)
        {
            cut = (cut + 1) % n;
        }
    }

    // Return position of survivor (1-based index)
    return cut + 1;
}

static void Main()
{
    int n = 7, k = 3;
    Console.WriteLine(josephus(n, k));
}

}

JavaScript

function josephus(n, k) {

// adjust for 0-based index
k--; 
let arr = new Array(n).fill(1); 

let cnt = 0, cut = 0, num = 1;

// Continue until n - 1 people are dead
while (cnt < n - 1) {

    // Find the k-th alive person
    while (num <= k) {
        cut++;
        cut = cut % n; 
        if (arr[cut] === 1) {
            num++;
        }
    }

    // Reset num for next round
    num = 1;

    // Kill the person at index 'cut'
    arr[cut] = 0;
    cnt++;
    
    // move to next
    cut = (cut + 1) % n; 

    // Skip dead persons
    while (arr[cut] === 0) {
        cut = (cut + 1) % n;
    }
}

// Return position of survivor (1-based index)
return cut + 1;

}

// Driver code let n = 7, k = 3; console.log(josephus(n, k));

`

[Expected Approach - 1] Using Recursive Relation - O(n) Time and O(n) Space

The Josephus problem can be solved recursively using the relation:
josephus(n,k) = (josephus(n−1,k)+k−1) % n + 1

The key idea is after each elimination, the circle shrinks, but the pattern of safe positions stays the same it’s just rotated. So if we know the safe position for n-1 people, we can shift it forward by k positions to get the safe position for n people. Repeat this shrinking-and-shifting idea until only 1 person remains, which is trivially safe.

Working:

#include using namespace std;

int josephus(int n, int k){ if (n == 1) return 1; else

    // The position returned by josephus(n - 1, k)
    // is adjusted because the recursive call
    // josephus(n - 1, k) considers the
    // original position k % n + 1 as position 1
    return (josephus(n - 1, k) + k - 1) % n + 1;

}

int main() {

int n = 7, k = 3;
cout <<  josephus(n, k);
return 0;

}

Java

class GFG {

static int josephus(int n, int k){
    if (n == 1)
        return 1;
    else
        /* The position returned by josephus(n - 1, k)
        is adjusted because the recursive call
        josephus(n - 1, k) considers the original
        position k%n + 1 as position 1 */
        return (josephus(n - 1, k) + k - 1) % n + 1;
}

public static void main(String[] args) {
    int n = 7, k = 3;
    System.out.println( josephus(n, k));
}

}

Python

def josephus(n, k):

if (n == 1):
    return 1
else:

    # The position returned by
    # josephus(n - 1, k) is adjusted
    # because the recursive call
    # josephus(n - 1, k) considers
    # the original position
    # k % n + 1 as position 1
    return (josephus(n - 1, k) + k-1) % n + 1

if name == "main": n = 7 k = 3

print(josephus(n, k))

C#

using System;

class GFG {

static int josephus(int n, int k) {
    if (n == 1)
        return 1;
    else
        /* The position returned
        by josephus(n - 1, k) is
        adjusted because the
        recursive call josephus(n
        - 1, k) considers the
        original position k%n + 1
        as position 1 */
        return (josephus(n - 1, k) + k - 1) % n + 1;
}
public static void Main() {
    int n = 7, k = 3;
    Console.WriteLine(josephus(n, k));
}

}

JavaScript

function josephus(n, k) { if (n == 1) return 1; else /* The position returned by josephus(n - 1, k) is adjusted because the recursive call josephus(n - 1, k) considers the original position k%n + 1 as position 1 */ return (josephus(n - 1, k) + k-1) % n + 1; } //Driven Code let n = 7; let k = 3; console.log( josephus(n, k));

`

[Expected Approach - 2] Iterative Mathematical Approach - O(n) Time and O(1) Space

We can solve this iteratively by building the solution from 1 person up to n.

#include using namespace std;

int josephus(int n, int k){

// Initialize variables i and ans with 1 and 0
// respectively.
int i = 1, ans = 0;

// Run a while loop till i <= n
while (i <= n) {

    // Update the Value of ans and Increment i by 1
    ans = (ans + k) % i;
    i++;
}

// Return required answer
return ans + 1;

}

int main(){

int n = 7, k = 3;
cout << josephus(n, k) << endl;
return 0;

}

Java

class GFG { public static int josephus(int n, int k) {

// Initialize variables i and ans with 1 and 0 
// respectively.
int i = 1, ans = 0;

// Run a while loop till i <= n
while (i <= n) {

  // Update the Value of ans and Increment i by 1
  ans = (ans + k) % i;
  i++;
}

// Return required answer
return ans + 1;

}

public static void main (String[] args) {

int n = 7, k = 3;
int ans = josephus(n, k);
System.out.println(ans);

} }

Python

def josephus(n, k):

#  Initialize variables i and ans with 1 and 0 
#  respectively.
i = 1
ans = 0

# Run a while loop till i <= n
while(i <= n):

    # update the value of ans
    ans = (ans + k) % i
    i += 1

# returning the required answer
return ans + 1

if name == "main": n = 7 k = 3

result = josephus(n, k)
print(result)

C#

using System;

class GFG { public static int josephus(int n, int k){

    // Initialize variables i and ans with 1 and 0 respectively.
    int i = 1, ans = 0;

    // Run a while loop till i <= n
    while (i <= n){
        
        // Update the Value of ans and Increment i by 1
        ans = (ans + k) % i;
        i++;
    }

    // Return required answer
    return ans + 1;
}

static void Main(string[] args) {
    int n = 7, k = 3;
    int ans = josephus(n, k);
    Console.WriteLine(ans);
}

}

JavaScript

function josephus(n, k){

// Initialize variables i and ans with 1 and 0 respectively.
let i = 1, ans = 0;

// Run a while loop till i <= n
while(i <= n ) {

    // update the value of ans 
    ans = (ans + k) % i;
    i++;
}

// Return required answer
return ans + 1;

}

// Driver code let n = 7, k = 3; console.log(josephus(n,k));

`

**Related Article: Josephus problem | Set 2 (A Simple Solution when k = 2)