Open In App

Policemen catch thieves

Last Updated : 27 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr, where each element represents either a policeman (P) or a thief (T). The objective is to determine the maximum number of thieves that can be caught under the following conditions:

  • Each policeman (P) can catch only one thief (T).
  • A policeman can only catch a thief if the distance between them is at most k units.

Your task is to find the maximum number of thieves that can be caught following these rules.

Examples: 

Input: arr[] = ['P', 'T', 'T', 'P', 'T'], k = 1
Output: 2.
Explanations: Here maximum 2 thieves can be caught, first
policeman catches first thief and second police man can catch either second or third thief.

Input: arr[] = ['T', 'T', 'P'], k = 1
Output: 1
Explanations: Here second thief can be caught by the police.

[Naive Approach] Using Nested loops - O(n*k) Time and O(n) Space

The main idea is that for every policeman, we search for a thief within a range of 2*k + 1 in a sequential manner. If a thief is found, we insert their index into the caught array to ensure that the same thief is not caught multiple times.

Step by Step implementation:

  • We traverse the array from left to right.
  • If the current element is a policeman (P), search for a thief (T) within a range of [i - k, i + k].
  • Each thief can be caught only once, so we track caught thieves using an auxiliary array.
  • If a thief is found within this range who is not already caught, mark them as caught and increase the count.
  • Return the count of caught thieves.
C++
// C++ program to find maximum number of thieves
// caught
#include <bits/stdc++.h>
using namespace std;

// Returns maximum number of thieves that can
// be caught.
int catchThieves(vector<char> &arr, int k) {
    int n = arr.size();
    
    // To mark if a thief is caught
    vector<bool> caught(n, false); 
    
    // Stores the number of caught thieves
    int count = 0; 
    for (int i = 0; i < n; ++i) {
        if (arr[i] == 'P') { 
            int start = max(0, i - k); 
            int end = min(n - 1, i + k); 
            
            // Search for an uncaught thief within range
            for (int j = start; j <= end; ++j) {
                if (arr[j] == 'T' && !caught[j]) { 
                    caught[j] = true; 
                    count++; 
                    break; 
                }
            }
        }
    }
    return count; 
}
int main() {
    int k = 1;
    vector<char> arr = { 'P', 'T', 'T', 'P', 'T' };
    cout<< catchThieves(arr, k) << endl;
}
Java
// Java program to find maximum number of thieves
// caught
import java.util.*;

public class GfG {
    
    // Function to find the maximum number of thieves
    // that can be caught
     static int catchThieves(char[] arr, int k) {
        int n = arr.length;
        
        // Boolean array to keep track of caught thieves
        boolean[] caught = new boolean[n]; 
        
        // Count of caught thieves
        int count = 0; 
        
        // Traverse the array to find policemen
        for (int i = 0; i < n; i++) {
            
            // Found a policeman
            if (arr[i] == 'P') { 
                int start = Math.max(0, i - k); 
                int end = Math.min(n - 1, i + k); 
                
                // Search for an uncaught thief within range
                for (int j = start; j <= end; j++) {
                    if (arr[j] == 'T' && !caught[j]) { 
                        caught[j] = true; 
                        count++; 
                        break; 
                    }
                }
            }
        }
        return count; 
    }

    public static void main(String[] args) {
        int k = 1;
        char[] arr = { 'P', 'T', 'T', 'P', 'T' };
        
        System.out.println(catchThieves(arr, k)); 
    }
}
Python
# Python program to find the maximum number of thieves caught

# Returns the maximum number of thieves that can be caught
def catchThieves(arr, k):
    n = len(arr)
    
    # To mark if a thief is caught
    caught = [False] * n  
    
    # Stores the number of caught thieves
    count = 0  
    
    for i in range(n):
        if arr[i] == 'P':  
            start = max(0, i - k)  
            end = min(n - 1, i + k)  
            
            # Search for an uncaught thief within range
            for j in range(start, end + 1):
                if arr[j] == 'T' and not caught[j]:  
                    caught[j] = True  
                    count += 1  
                    break  
    
    return count  

if __name__ == "__main__":
    k = 1
    arr = ['P', 'T', 'T', 'P', 'T']
    print(catchThieves(arr, k)) 
C#
using System;

class GfG {
    
    // Returns the maximum number of thieves that can be caught
    static int catchThieves(char[] arr, int k) {
        int n = arr.Length;
        
        // To mark if a thief is caught
        bool[] caught = new bool[n]; 
        
        // Stores the number of caught thieves
        int count = 0; 
        
        for (int i = 0; i < n; i++)
        {
            if (arr[i] == 'P')
            {
                int start = Math.Max(0, i - k);
                int end = Math.Min(n - 1, i + k);
                
                // Search for an uncaught thief within range
                for (int j = start; j <= end; j++)
                {
                    if (arr[j] == 'T' && !caught[j])
                    {
                        caught[j] = true;
                        count++;
                        break;
                    }
                }
            }
        }
        return count;
    }

    static void Main() {
        int k = 1;
        char[] arr = { 'P', 'T', 'T', 'P', 'T' };
        
        Console.WriteLine(catchThieves(arr, k));  
    }
}
JavaScript
// JavaScript program to find the maximum number of thieves caught

// Returns the maximum number of thieves 
// that can be caught
function catchThieves(arr, k) {
    let n = arr.length;
    
    // To mark if a thief is caught
    let caught = new Array(n).fill(false); 
    
    // Stores the number of caught thieves
    let count = 0; 
    
    for (let i = 0; i < n; i++) {
        if (arr[i] === 'P') {
            let start = Math.max(0, i - k);
            let end = Math.min(n - 1, i + k);
            
            // Search for an uncaught thief within range
            for (let j = start; j <= end; j++) {
                if (arr[j] === 'T' && !caught[j]) { 
                    caught[j] = true;
                    count++;
                    break;
                }
            }
        }
    }
    return count;
}

// Driver Code
const k = 1;
const arr = ['P', 'T', 'T', 'P', 'T'];

console.log(catchThieves(arr, k)); 

Output
2

[Expected Approach] Using Two Pointers - O(n) Time and O(1) Space

The main idea is to use two pointers (both begin from left side): one to track policemen and the other to track thieves.

We traverse the array while maintaining these pointers.

  • If a policeman and a thief are within the allowed range k, the thief is caught, and both pointers move forward.
  • If the thief is too far left, we move the thief pointer forward;
  • similarly, if the policeman is too far left, we move the policeman pointer forward.

Step by Step implementation:

  • Initialize Two Pointers: i for the next policeman ('P') and j for the next thief ('T'), along with a counter count = 0.
  • Traverse the Array: Move i to the next 'P' and j to the next 'T'.
  • Check Distance: If |i - j| ≤ k, catch the thief (count++), then move both pointers forward.
  • Adjust Pointers: If the thief (j) is too far left, move j forward; if the policeman (i) is too far left, move i forward.
  • Repeat Until End: Continue until either i or j reaches the end of the array. Return count.
C++
// C++ program to find maximum number of thieves
// caught
#include <bits/stdc++.h>
using namespace std;

// Returns the maximum number of thieves
// that can be caught using two pointers
int catchThieves(vector<char> &arr, int k) {
    int n = arr.size();
    
    // Two pointers for policemen and thieves
    int i = 0, j = 0; 
    int count = 0;

    while (i < n && j < n) {
        
        // Move i to the next policeman
        while (i < n && arr[i] != 'P') i++;

        // Move j to the next thief
        while (j < n && arr[j] != 'T') j++;

        // If both policeman and thief exist and are within range k
        if (i < n && j < n && abs(i - j) <= k) {
            
            // Catch the thief
            count++; 
            
            // Move to the next policeman
            i++; 
            
            // Move to the next thief
            j++; 
        } 
        
        // If the thief is too far left, move the thief pointer
        else if (j < n && j < i) {
            j++;
        } 
        
        // If the policeman is too far left, 
        // move the policeman pointer
        else if (i < n && i < j) {
            i++;
        }
    }
    return count;
}

int main() {
    int k = 1;
    vector<char> arr = { 'P', 'T', 'T', 'P', 'T' };
    cout<< catchThieves(arr, k) << endl;
}
Java
// Java program to find maximum number of thieves
// caught
import java.util.*;

public class GfG {
    
    // Returns the maximum number of thieves that
    // can be caught using two pointers
    static int catchThieves(char[] arr, int k) {
        int n = arr.length;

        // Two pointers for policemen and thieves
        int i = 0, j = 0;
        int count = 0;

        while (i < n && j < n) {
            
            // Move i to the next policeman
            while (i < n && arr[i] != 'P') i++;

            // Move j to the next thief
            while (j < n && arr[j] != 'T') j++;

            // If both policeman and thief exist 
            // and are within range k
            if (i < n && j < n && Math.abs(i - j) <= k) {
                
                // Catch the thief
                count++;  
                
                // Move to the next policeman
                i++;  
                
                // Move to the next thief
                j++;  
            } 
            
            // If the thief is too far left,
            // move the thief pointer
            else if (j < n && j < i) {
                j++;
            } 
            
            // If the policeman is too far left,
            // move the policeman pointer
            else if (i < n && i < j) {
                i++;
            }
        }
        return count;
    }

    public static void main(String[] args) {
        int k = 1;
        char[] arr = { 'P', 'T', 'T', 'P', 'T' };
        
        System.out.println(catchThieves(arr, k)); 
    }
}
Python
# Python program to find the maximum number of thieves caught

# Returns the maximum number of thieves 
# that can be caught using two pointers
def catchThieves(arr, k):
    n = len(arr)
    
    # Two pointers for policemen and thieves
    i, j = 0, 0
    count = 0

    while i < n and j < n:
        
        # Move i to the next policeman
        while i < n and arr[i] != 'P':
            i += 1

        # Move j to the next thief
        while j < n and arr[j] != 'T':
            j += 1

        # If both policeman and thief exist
        # and are within range k
        if i < n and j < n and abs(i - j) <= k:
            
            # Catch the thief
            count += 1  
            
            # Move to the next policeman
            i += 1  
            
            # Move to the next thief
            j += 1  
        
        # If the thief is too far left,
        # move the thief pointer
        elif j < n and j < i:
            j += 1
        
        # If the policeman is too far left,
        # move the policeman pointer
        elif i < n and i < j:
            i += 1

    return count 

if __name__ == "__main__":
    k = 1
    arr = ['P', 'T', 'T', 'P', 'T']
    print(catchThieves(arr, k)) 
C#
using System;

class GfG {
    
     static int catchThieves(char[] arr, int k) {
        int n = arr.Length;
        
        // Two pointers for policemen and thieves
        int i = 0, j = 0; 
        int count = 0;

        while (i < n && j < n) {
            
            // Move i to the next policeman
            while (i < n && arr[i] != 'P') 
                i++;

            // Move j to the next thief
            while (j < n && arr[j] != 'T') 
                j++;

            // If both policeman and thief exist
            // and are within range k
            if (i < n && j < n && Math.Abs(i - j) <= k) {
                
                // Catch the thief
                count++;

                // Move to the next policeman
                i++; 

                // Move to the next thief
                j++; 
            }
            
            // If the thief is too far left, move the thief pointer
            else if (j < n && j < i) {
                j++;
            }
            
            // If the policeman is too far left,
            // move the policeman pointer
            else if (i < n && i < j) {
                i++;
            }
        }
        return count;
    }

    static void Main() {
        int k = 1;
        char[] arr = { 'P', 'T', 'T', 'P', 'T' };
        
        Console.WriteLine(catchThieves(arr, k));  
    }
}
JavaScript
// JavaScript program to find the maximum number of thieves caught

// Returns the maximum number of thieves 
// that can be caught
function catchThieves(arr, k) {
    let n = arr.length;

    // Two pointers for policemen and thieves
    let i = 0, j = 0;
    let count = 0;

    while (i < n && j < n) {
        
        // Move i to the next policeman
        while (i < n && arr[i] !== 'P') i++;

        // Move j to the next thief
        while (j < n && arr[j] !== 'T') j++;

        // If both policeman and thief exist and are within range k
        if (i < n && j < n && Math.abs(i - j) <= k) {
            
            // Catch the thief
            count++;

            // Move to the next policeman
            i++;

            // Move to the next thief
            j++;
        } 
        
        // If the thief is too far left, move the thief pointer
        else if (j < n && j < i) {
            j++;
        } 
        
        // If the policeman is too far left, move the policeman pointer
        else if (i < n && i < j) {
            i++;
        }
    }
    return count;
}

// Driver Code
const k = 1;
const arr = ['P', 'T', 'T', 'P', 'T'];

console.log(catchThieves(arr, k)); 

Output
2

Similar Reads