Problem Statement
There are N people standing in a circle numbered from 1 to N. Also given an integer K. First, count the K-th number starting from the first one and delete it. Then K numbers are counted starting from the next one and the K-th one is removed again, and so on. The process stops when one number remains. The task is to find the last number.
Examples:
- Input: N = 6, K = 2
- Output: 5
Explanation:
Recursive Approach
A simple approach to solve this problem is to find the position of the step which would be called after each execution.
Therefore, given N persons, and skipping K persons during their deletion, N – 1 persons will be left. Therefore, we need to call the recursive function for N – 1 and K for the next iteration.
Now, for each remaining circle after execution, we need to find the last remaining person present i.e. if Kth person is executed, K+1th will be the next starting safe point the recursive call. Therefore, to keep a track of the position, perform K%N + 1.
The recursive function would be:
josephus(N, K) = (josephus(N – 1 , K) + K – 1) % N + 1.
You can also observe a pattern as follows:
Algorithm
- If N == 1, return 1. This is the termination condition for the function.
- Else, return (josephus(N – 1 , K) + K – 1) % N + 1.
C++ Code
int josephus(int N, int K) { if (N == 1) return 1; else return (josephus(N - 1, K) + K - 1) % N + 1; }
Java Code
static int josephus(int N, int K) { if (N == 1) return 1; else return (josephus(N - 1, K) + K - 1) % N + 1; }
Python Code
def josephus(N, K): if N == 1: return 1 else: return (josephus(N - 1, K) + K - 1) % N + 1
- Time Complexity: O(N)
- Space Complexity: O(N), depth of the recursion tree.
Using List – Approach 2
In this approach, initialize a list containing all integers from 1 to N and delete every Kth node until one element is left.
Algorithm
- Create a list containing integers from 1 to N.
- Create a recursive function which deletes every Kth element from the list in each iteration in the clockwise direction.
- Continue repeating the above steps until only one element is left.
Implementation of the Approach:
C++ Code
void Josh(vector < int > person, int k, int index) { if (person.size() == 1) { cout << person[0] << endl; return; } index = ((index + k) % person.size()); person.erase(person.begin() + index); Josh(person, k, index); } solve(n, k) { k--; int index = 0; vector < int > person; for (int i = 1; i <= n; i++) { person.push_back(i); } Josh(person, k, index); }
Java Code
static void Josh(ArrayList < Integer > person, int k, int index) { if (person.size == 1) { System.out.println(person.get(0)); return; } index = ((index + k) % person.size()); person.remove(index); Josh(person, k, index); } solve(int N, int K) { K = K - 1; int index = 0; Arraylist < Integer > person; for (int i = 1; i <= N; i++) { person.push_back(i); } Josh(person, K, index); }
Python Code
def Josh(person, k, index): if len(person) == 1: print(person[0]) return index = (index + k) % len(person) person.pop(index) Josh(person, k, index) def solve(N, K): K = K - 1 index = 0 persons = [0] * (N) for i in range(1, N + 1): person.append(i) Josh(person, K, index)
- Time Complexity: O(N), where N is total persons.
- Space Complexity: O(N), a list of size N, is used.
Special Case: K = 2
For K = 2, the problem becomes much easier to solve.
In case, N is even, first all even positions will get deleted. Then, the remaining N / 2 remains. Therefore, the answer for the remaining N can be found from the answer for N / 2 by multiplying it with 2 and subtracting 1 i.e. shifting the positions.
The answer for even N can obtained as –
josephus(2 * N, 2) = josephus(N, 2) – 1
Similarly, In case, N is odd, first, all even positions will get deleted. Then, remaining (N – 1) / 2 remains. Therefore, the answer for the remaining N can be found from the answer for (N – 1) / 2 by multiplying it with 2 and subtracting 1 i.e. shifting the positions.
The answer for even N can obtained as –
josephus(2 * N + 1, 2) = josephus(N, 2) – 1
From the above relations, both can be merged and can be written as –
josephus(N, 2) = 1 + 2 * (N – 2 ^(floor(log2(N))
C++ Code
int josephus(int N) { int p = 1; while (p <= N) p *= 2; return (2 * N) - p + 1; }
Java Code
static int josephus(int N) { int p = 1; while (p <= N) p *= 2; return (2 * N) - p + 1; }
Python Code
def josephus(N): p = 1 while p <= N: p *= 2 return (2 * N) - p + 1
- Time Complexity: O(logN), where N is the total steps.
- Space Complexity: O(1), as no extra s[ace is used.
Practice Question
FAQs
Q.1: What data structure is used in solving the Josephus problem?
Ans: A list can be used to solve the Josephus problem, which initially contains all the integers from 1 to N.
Q.2: How to solve the Josephus problem?
Ans: The Josephus problem can be solved using recursion. For each iteration, recursively delete the Kth position until only one person is left.