Open In App

Josephus Problem | Set 3 (using STL)

Last Updated : 26 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given N persons are standing in a circle and an integer K. If initially starting from the first position, the Kth alive person clockwise from the current position is killed, and then the current position is shifted to the position of (K+1)th alive person and the same step is performed until only one person remains, the task is to print the position of the last alive person.

Examples:

Input: N = 5, K = 2
Output: 3
Explanation: 
One way to perform the operations is:

  1. Step 1: Initially, the counting starts from position 1. Therefore, the Kth alive person at position 2 is killed, so the remaining alive persons are at positions {1, 3, 4, 5}.
  2. Step 2: Now, the counting starts from position 3. Therefore, the Kth alive person at position 4 is killed, so the remaining alive persons are at positions {1, 3, 5}.
  3. Step 3: Now, the counting starts from position 5. Therefore, the Kth alive person at position 1 is killed, so the remaining alive persons are at positions {3, 5}.
  4. Step 4: Now, the counting starts from position 3. Therefore, the Kth alive person at position 5 is killed, so the last alive person is at position 3.

Therefore, the last remaining person living is at position 3.

Input: N = 10, K = 4
Output: 5

Different approaches to solve this problem are discussed in Set 1 and Set 2 of this article.

Approach 1(Using Vector): The above-given problem is known as Josephus’s problem. The problem can be solved using recursion and vector data structure from the STL library. Follow the steps below to solve the problem: 

  • Initialize a vector say, arr[] to store the positions of all the persons.
  • Iterate in the range [1, N] using the variable i and in each iteration append i to the vector arr[].
  • Define a recursive function say RecursiveJosephus(vector<int>:: iterator it, vector<int>arr), where it points to the current alive person from where K elements are to be counted.
  • Finally, after completing the above steps, call the function RecursiveJosephus(arr.begin(), arr) and print the value returned by it as the position of the last alive person.

Below is the implementation of the above approach:

C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;

// Recursive auxiliary function to find
// the position of thevlast alive person
int RecursiveJosephus(vector<int>& arr, int K,
                      vector<int>::iterator it)
{
    // If size of arr is 1
    if (arr.size() == 1) {
        return arr[0];
    }

    // Iterate over the range [1, K-1]
    for (int i = 1; i < K; i++) {

        // Increment it by 1
        it++;

        // If it is equal to arr.end()
        if (it == arr.end()) {

            // Assign arr.begin() to it
            it = arr.begin();
        }
    }

    // If it is equal to prev(arr.end())
    if (it == prev(arr.end())) {

        // Assign arr.begin() to it
        it = arr.begin();

        // Remove the last element
        arr.pop_back();
    }
    else {

        // Erase the element at it
        arr.erase(it);
    }

    // Return the last alive person
    return RecursiveJosephus(arr, K, it);
}

// Function to find the position of the
// last alive person
int Josephus(int N, int K)
{
    // Stores positions of every person
    vector<int> arr;
    for (int i = 1; i <= N; i++)
        arr.push_back(i);

    // Function call to find the position
    // of the last alive person
    return RecursiveJosephus(arr, K, arr.begin());
}

// Driver Code
int main()
{
    // Given Input
    int N = 5;
    int K = 2;

    // Function Call
    cout << Josephus(N, K);
}
Java
import java.util.List;
import java.util.ArrayList;

public class Main {

  // Recursive auxiliary function to find
  // the position of the last alive person
  public static int recursiveJosephus(List<Integer> arr, int K, int it) {

    // If size of arr is 1
    if (arr.size() == 1) {
      return arr.get(0);
    }
    
    // Iterate over the range [1, K-1]
    for (int i = 1; i < K; i++) {
      
      // Increment it by 1
      it++;
      if (it == arr.size()) {
        it = 0;
      }
    }
    if (it == arr.size() - 1) {
      // Remove the eliminated person from the list
      it = 0;
      arr.remove(arr.size() - 1);
    } else {
      arr.remove(it);
    }
    // Recursively call the function with the new list of people
    return recursiveJosephus(arr, K, it);
  }

  // Function to find the position of the last alive person
  public static int josephus(int N, int K) {
    
    // Create a list of people
    List<Integer> arr = new ArrayList<Integer>();
    for (int i = 1; i <= N; i++) {
      arr.add(i);
    }
    
    // Call the recursive function to find the position of the last alive person
    return recursiveJosephus(arr, K, 0);
  }

  // Driver code
  public static void main(String[] args) {
    int N = 5;
    int K = 2;
    System.out.println(josephus(N, K));
  }
}
C#
using System;
using System.Collections.Generic;

public class MainClass
{
  // Recursive auxiliary function to find
  // the position of the last alive person
  public static int RecursiveJosephus(List<int> arr, int K, int it)
  {
    // If size of arr is 1
    if (arr.Count == 1)
    {
      return arr[0];
    }

    // Iterate over the range [1, K-1]
    for (int i = 1; i < K; i++)
    {
      // Increment it by 1
      it++;
      if (it == arr.Count)
      {
        it = 0;
      }
    }

    if (it == arr.Count - 1)
    {
      // Remove the eliminated person from the list
      it = 0;
      arr.RemoveAt(arr.Count - 1);
    }
    else
    {
      arr.RemoveAt(it);
    }

    // Recursively call the function with the new list of people
    return RecursiveJosephus(arr, K, it);
  }

  // Function to find the position of the last alive person
  public static int Josephus(int N, int K)
  {
    // Create a list of people
    List<int> arr = new List<int>();
    for (int i = 1; i <= N; i++)
    {
      arr.Add(i);
    }

    // Call the recursive function to find the position of the last alive person
    return RecursiveJosephus(arr, K, 0);
  }

  // Driver code
  public static void Main()
  {
    int N = 5;
    int K = 2;
    Console.WriteLine(Josephus(N, K));
  }
}
Javascript
// JavaScript code
//Recursive auxiliary function to find
// the position of thevlast alive person
function recursiveJosephus(arr, K, it) {
  //If size of arr is 1
  if (arr.length === 1) {
    return arr[0];
  }
  //Iterate over the range [1, K-1]
  for (let i = 1; i < K; i++) {
    // Increment it by 1
    it += 1;
    if (it == arr.length) {
      it = 0;
    }
  }
  if (it == arr.length - 1) { // Remove the eliminated person from the list
    it = 0;
    arr.pop();
  } else {
    arr.splice(it, 1);
    // Recursively call the function with the new list of people
  }
  return recursiveJosephus(arr, K, it);
}
//Function to find the position of the last alive person
function josephus(N, K) {
  // Create a list of people
  let arr = [];
  for (let i = 1; i <= N; i++) {
    arr.push(i);
  }
  // Call the recursive function to find the position of the last alive person
  return recursiveJosephus(arr, K, 0);
}
//Driver code
  const N = 5;
  const K = 2;
  console.log(josephus(N, K));
Python3
# Python program for the above approach
from typing import List
# Recursive auxiliary function to find
# the position of thevlast alive person
def RecursiveJosephus(arr: List[int], K: int, it: int):
      #If size of arr is 1

    if len(arr) == 1:
        return arr[0]
 #Iterate over the range [1, K-1]

    for i in range(1, K):
       # Increment it by 1

        it += 1
        if it == len(arr):
            it = 0
    if it == len(arr) - 1: # Remove the eliminated person from the list

        it = 0
        arr.pop()
    else:
        arr.pop(it)
        # Recursively call the function with the new list of people

    return RecursiveJosephus(arr, K, it)
#Function to find the position of the last alive person
def Josephus(N: int, K: int):
  # Create a list of people

    arr = list(range(1, N+1))
    # Call the recursive function to find the position of the last alive person

    return RecursiveJosephus(arr, K, 0)
#Driver code

if __name__ == '__main__':
    N = 5
    K = 2
    print(Josephus(N, K))

Output
3

Time Complexity: O(N2)
Auxiliary Space: O(N)

Approach 2(Using SET): The problem can be solved using recursion and a set data structure from the STL library. Follow the steps below to solve the problem: 

  • Initialize a set say, arr to store the positions of all the persons.
  • Iterate in the range [1, N] using the variable i, and in each iteration insert i in the set arr.
  • Define a recursive function say RecursiveJosephus(set<int>:: iterator it, set<int>arr), where it points to the position of the current alive person from where K elements are to be counted.
    • If the size of the set arr is 1, then return the value pointed by the iterator, it.
    • Iterate in the range [1, K-1] and then, in each iteration, increment it by 1 and if it becomes equal to arr. end(), then assign arr.begin() to it.
    • Now if it is pointing to the position of the last element of the set, arr, then delete the last element of the set, arr, and then update it with the position of the (K+1)th, person i.e arr.begin().
    • Otherwise, store the value of the next iterator of it in a variable, say val then erase the position pointed by it.
    • After deletion, it becomes invalid. Therefore, now find the value of val in the set, arr, and then assign it to it. Now it points to the position of the (K+1)th living person.
  • Finally, after completing the above steps, call the function RecursiveJosephus(arr.begin(), arr) and print the value returned by it as the position of the last living person.

Below is the implementation of the above approach:

C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;

// Recursive auxiliary function to find
// the position of the last alive person
int RecursiveJosephus(set<int>& arr, int K,
                      set<int>::iterator it)
{

    // If size of arr is 1
    if (arr.size() == 1) {
        return *it;
    }

    // Iterate over the range [1, K-1]
    for (int i = 1; i < K; i++) {

        // Increment it by 1
        it++;

        // If it is equal to arr.end()
        if (it == arr.end()) {

            // Assign arr.begin() to it
            it = arr.begin();
        }
    }

    // If it is equal to prev(arr.end())
    if (it == prev(arr.end())) {

        // Assign arr.begin() to it
        it = arr.begin();

        // Remove the last element
        arr.erase(prev(arr.end()));
    }
    else {

        // Stores the value pointed
        // by next iterator of it
        int val = (*next(it));

        // Erase the element at it
        arr.erase(it);

        // Update it
        it = arr.find(val);
    }

    // Return the position of
    // the last alive person
    return RecursiveJosephus(arr, K, it);
}

// Function to find the position
// of the last alive person
int Josephus(int N, int K)
{
    // Stores all the persons
    set<int> arr;

    for (int i = 1; i <= N; i++)
        arr.insert(i);

    // Function call to find the position
    // of the last alive person
    return RecursiveJosephus(arr, K, arr.begin());
}

// Driver Code
int main()
{
    // Given Input
    int N = 5;
    int K = 2;

    // Function Call
    cout << Josephus(N, K);
}
Java
import java.util.*;

// Java program for the above approach
public class Main {

    // Function to find the position
    // of the last alive person
    public static int josephus(int N, int K) {

        // Stores all the persons
        List<Integer> arr = new ArrayList<>();
        for (int i = 1; i <= N; i++)
            arr.add(i);

        int killIdx = 0;
        while (arr.size() > 1) {
            killIdx = (killIdx + K - 1) % arr.size(); // -1 because index starts from 0
            arr.remove(killIdx);
        }

        // Return the position of
        // the last alive person
        return arr.get(0);
    }

    // Driver Code
    public static void main(String[] args) {

        // Given Input
        int N = 5;
        int K = 2;

        // Function Call
        System.out.println(josephus(N, K));
    }
}
JavaScript
// Recursive auxiliary function to find
// the position of the last alive person
function recursiveJosephus(arr, K, it) {
    // If size of arr is 1
    if (arr.length === 1) {
        return arr[0];
    }

    // Calculate the next index after removal
    let nextIndex = (it + K) % arr.length;

    // Remove the element at nextIndex
    arr.splice(nextIndex, 1);

    // Adjust the iterator if necessary
    if (nextIndex === arr.length) {
        nextIndex = 0;
    }

    // Return the result of the recursive call
    return recursiveJosephus(arr, K, nextIndex);
}

// Function to find the position
// of the last alive person
function josephus(N, K) {
    // Stores all the persons
    let arr = [];

    for (let i = 1; i <= N; i++)
        arr.push(i);

    // Function call to find the position
    // of the last alive person
    return recursiveJosephus(arr, K - 1, 0);
}

// Driver Code
function main() {
    // Given Input
    let N = 5;
    let K = 2;

    // Function Call
    console.log(josephus(N, K));
}

// Call the main function
main();
Python3
def recursive_josephus(arr, K, it):
    if len(arr) == 1:
        return arr[0]

    next_it = (it + K - 1) % len(arr)
    arr.pop(next_it)
    return recursive_josephus(arr, K, next_it % len(arr))

def josephus(N, K):
    arr = list(range(1, N + 1))
    return recursive_josephus(arr, K, 0)

# Driver Code
if __name__ == "__main__":
    N = 5
    K = 2
    print(josephus(N, K))

Output
3

Time Complexity: O(N*K+N*log(N))
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads