Policemen catch thieves

08 Jun, 2022
Given an array of size n that has the following specifications: 
Each element in the array contains either a policeman or a thief.Each policeman can catch only one thief.A policeman cannot catch a thief who is more than K units away from the policeman.
Each element in the array contains either a policeman or a thief.
Each policeman can catch only one thief.
A policeman cannot catch a thief who is more than K units away from the policeman.
We need to find the maximum number of thieves that can be caught.Examples:  
Input : arr[] = {'P', 'T', 'T', 'P', 'T'},
            k = 1.
Output : 2.
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', 'P', 'T', 'P'}, 
            k = 2.
Output : 3.

Input : arr[] = {'P', 'T', 'P', 'T', 'T', 'P'},
            k = 3.
Output : 3.
A brute force approach would be to check all feasible sets of combinations of police and thief and return the maximum size set among them. Its time complexity is exponential and it can be optimized if we observe an important property. An efficient solution is to use a greedy algorithm. But which greedy property to use can be tricky. We can try using: “For each policeman from the left catch the nearest possible thief.” This works for example three given above but fails for example two as it outputs 2 which is incorrect. We may also try: “For each policeman from the left catch the farthest possible thief”. This works for example two given above but fails for example three as it outputs 2 which is incorrect. A symmetric argument can be applied to show that traversing for these from the right side of the array also fails. We can observe that thinking irrespective of the policeman and focusing on just the allotment works: 1. Get the lowest index of policeman p and thief t. Make an allotment if |p-t| <= k and increment to the next p and t found. 2. Otherwise increment min(p, t) to the next p or t found. 3. Repeat above two steps until next p and t are found. 4. Return the number of allotments made.Below is the implementation of the above algorithm. It uses vectors to store the indices of police and thief in the array and processes them.  
C++
Java
C#
Python3
Javascript
// 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 policeThief(char arr[], int n, int k){  int res = 0;  vector<int> thi;  vector<int> pol;   // store indices in the vector  for (int i = 0; i < n; i++) {    if (arr[i] == 'P')      pol.push_back(i);    else if (arr[i] == 'T')      thi.push_back(i);  }   // track lowest current indices of  // thief: thi[l], police: pol[r]  int l = 0, r = 0;  while (l < thi.size() && r < pol.size()) {    // can be caught    if (abs(thi[l++] - pol[r++]) <= k)      res++;    // increment the minimum index    else if (thi[l] < pol[r])      l++;    else      r++;  }  return res;} int main(){  int k, n;  char arr1[] = { 'P', 'T', 'T', 'P', 'T' };  k = 2;  n = sizeof(arr1) / sizeof(arr1[0]);  cout << "Maximum thieves caught: " << policeThief(arr1, n, k) << endl;   char arr2[] = { 'T', 'T', 'P', 'P', 'T', 'P' };  k = 2;  n = sizeof(arr2) / sizeof(arr2[0]);  cout << "Maximum thieves caught: " << policeThief(arr2, n, k) << endl;   char arr3[] = { 'P', 'T', 'P', 'T', 'T', 'P' };  k = 3;  n = sizeof(arr3) / sizeof(arr3[0]);  cout << "Maximum thieves caught: " << policeThief(arr3, n, k) << endl;  return 0;} // This code is contributed by Aditya Kumar (adityakumar129)
// Java program to find maximum number of// thieves caughtimport java.util.*;import java.io.*; class GFG{  // Returns maximum number of thieves  // that can be caught.  static int policeThief(char arr[], int n, int k)  {    int res = 0;    ArrayList<Integer> thi = new ArrayList<Integer>();    ArrayList<Integer> pol = new ArrayList<Integer>();     // store indices in the ArrayList    for (int i = 0; i < n; i++) {      if (arr[i] == 'P')        pol.add(i);      else if (arr[i] == 'T')        thi.add(i);    }     // track lowest current indices of    // thief: thi[l], police: pol[r]    int l = 0, r = 0;    while (l < thi.size() && r < pol.size()) {      // can be caught      if (Math.abs(thi.get(l++) - pol.get(r++)) <= k)        res++;      // increment the minimum index      else if (thi.get(l) < pol.get(r))        l++;      else        r++;    }    return res;  }   public static void main(String args[])  {    int k, n;    char arr1[] = new char[] { 'P', 'T', 'T', 'P', 'T' };    k = 2;    n = arr1.length;    System.out.println("Maximum thieves caught: " + policeThief(arr1, n, k));     char arr2[] = new char[] { 'T', 'T', 'P', 'P', 'T', 'P' };    k = 2;    n = arr2.length;    System.out.println("Maximum thieves caught: " + policeThief(arr2, n, k));     char arr3[] = new char[] { 'P', 'T', 'P', 'T', 'T', 'P' };    k = 3;    n = arr3.length;    System.out.println("Maximum thieves caught: " + policeThief(arr3, n, k));  }} // This code is contributed by Aditya Kumar (adityakumar129)
// C# program to find maximum number of// thieves caughtusing System;using System.Collections.Generic; public class GFG{         // Returns maximum number of thieves   // that can be caught.   static int policeThief(char[] arr, int n, int k)   {        int res = 0;        List<int> thi = new List<int>();        List<int> pol = new List<int>();              // store indices in the ArrayList        for (int i = 0; i < n; i++) {          if (arr[i] == 'P')            pol.Add(i);          else if (arr[i] == 'T')            thi.Add(i);        }              // track lowest current indices of        // thief: thi[l], police: pol[r]        int l = 0, r = 0;        while (l < thi.Count && r < pol.Count) {          // can be caught          if (Math.Abs(thi[l++] - pol[r++]) <= k){              res++;          }else{              if (thi[l] < pol[r]){                  l++;              }else{                  r++;              }          }        }        return res;    }         static public void Main (){        int k, n;        char[] arr1 = { 'P', 'T', 'T', 'P', 'T' };        k = 2;        n = arr1.Length;        Console.Write("Maximum thieves caught: " + policeThief(arr1, n, k)+"\n");              char[] arr2 = { 'T', 'T', 'P', 'P', 'T', 'P' };        k = 2;        n = arr2.Length;        Console.Write("Maximum thieves caught: " + policeThief(arr2, n, k)+"\n");              char[] arr3 = { 'P', 'T', 'P', 'T', 'T', 'P' };        k = 3;        n = arr3.Length;        Console.Write("Maximum thieves caught: " + policeThief(arr3, n, k)+"\n");    }} //This code is contributed by shruti456rawal
# Python3 program to find maximum# number of thieves caught # Returns maximum number of thieves# that can be caught.def policeThief(arr, n, k):    i = 0    l = 0    r = 0    res = 0    thi = []    pol = []     # store indices in list    while i < n:        if arr[i] == 'P':            pol.append(i)        elif arr[i] == 'T':            thi.append(i)        i += 1     # track lowest current indices of    # thief: thi[l], police: pol[r]    while l < len(thi) and r < len(pol):                 # can be caught        if (abs( thi[l] - pol[r] ) <= k):            res += 1            l += 1            r += 1                     # increment the minimum index        elif thi[l] < pol[r]:            l += 1        else:            r += 1     return res # Driver programif __name__=='__main__':    arr1 = ['P', 'T', 'T', 'P', 'T']    k = 2    n = len(arr1)    print(("Maximum thieves caught: {}".         format(policeThief(arr1, n, k))))     arr2 = ['T', 'T', 'P', 'P', 'T', 'P']    k = 2    n = len(arr2)    print(("Maximum thieves caught: {}".          format(policeThief(arr2, n, k))))     arr3 = ['P', 'T', 'P', 'T', 'T', 'P']    k = 3    n = len(arr3)    print(("Maximum thieves caught: {}".          format(policeThief(arr3, n, k)))) # This code is contributed by `jahid_nadim`
<script> // JavaScript program to find maximum// number of thieves caught // Returns maximum number of thieves// that can be caught.function policeThief(arr, n, k){    let i = 0    let l = 0    let r = 0    let res = 0    let thi = []    let pol = []     // store indices in list    while(i < n){        if(arr[i] == 'P')            pol.push(i)        else if(arr[i] == 'T')            thi.push(i)        i += 1    }     // track lowest current indices of    // thief: thi[l], police: pol[r]    while(l < thi.length && r < pol.length){                 // can be caught        if (Math.abs( thi[l] - pol[r] ) <= k){            res += 1            l += 1            r += 1        }                     // increment the minimum index        else if(thi[l] < pol[r])            l += 1        else            r += 1    }     return res} // Driver programlet arr1 = ['P', 'T', 'T', 'P', 'T']let k = 2let n = arr1.lengthdocument.write("Maximum thieves caught: ",policeThief(arr1, n, k),"</br>") let arr2 = ['T', 'T', 'P', 'P', 'T', 'P']k = 2n = arr2.lengthdocument.write("Maximum thieves caught: ",policeThief(arr2, n, k),"</br>") let arr3 = ['P', 'T', 'P', 'T', 'T', 'P']k = 3n = arr3.lengthdocument.write("Maximum thieves caught: ",policeThief(arr3, n, k),"</br>") // This code is contributed by shinjanpatra </script>
Maximum thieves caught: 2
Maximum thieves caught: 3
Maximum thieves caught: 3
Time Complexity: O(N) Auxiliary Space: O(N)
Following method works in O(1) space complexity
Approach:
This approach takes the following steps:
First find the left most police and thief and store the indices. There can be two cases:CASE 1: If the distance between the police and thief <= k (given), the thief can be caught, so increment the res counterCASE 2: If the distance between the police and thief >= k, the current thief cannot be caught by the current policeFor CASE 2, if the police is behind the thief, we need to find the next police and check if it can catch the current thiefif the thief is behind the police, we need to find the next thief and check if the current police can catch the thiefRepeat the process until we find the next police and thief pair, and increment result counter if conditions are met, i,e, CASE 1.
First find the left most police and thief and store the indices. There can be two cases:
CASE 1: If the distance between the police and thief <= k (given), the thief can be caught, so increment the res counter
CASE 2: If the distance between the police and thief >= k, the current thief cannot be caught by the current policeFor CASE 2, if the police is behind the thief, we need to find the next police and check if it can catch the current thiefif the thief is behind the police, we need to find the next thief and check if the current police can catch the thief
For CASE 2, if the police is behind the thief, we need to find the next police and check if it can catch the current thiefif the thief is behind the police, we need to find the next thief and check if the current police can catch the thief
For CASE 2, if the police is behind the thief, we need to find the next police and check if it can catch the current thief
if the thief is behind the police, we need to find the next thief and check if the current police can catch the thief
Repeat the process until we find the next police and thief pair, and increment result counter if conditions are met, i,e, CASE 1.
Algorithm:1. Initialize the current lowest indices of policeman in pol and thief in thi variable as -1.2 Find the lowest index of policeman and thief.3 If lowest index of either policeman or thief remain -1 then return 0.4 If |pol – thi| <=k then make an allotment and find the next policeman and thief.5 Else increment the min(pol , thi) to the next policeman or thief found.6 Repeat the above two steps until we can find the next policeman and thief.7 Return the number of allotments made.Below is the implementation of the above algorithm.
C++
C
Java
Javascript
Python3
// 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 policeThief(char arr[], int n, int k){  // Initialize the current lowest indices of  // policeman in pol and thief in thi variable as -1  int pol = -1, thi = -1, res = 0;  // Find the lowest index of policemen  for (int i = 0; i < n; i++) {    if (arr[i] == 'P') {      pol = i;      break;    }  }   // Find the lowest index of thief  for (int i = 0; i < n; i++) {    if (arr[i] == 'T') {      thi = i;      break;    }  }   // If lowest index of either policemen or thief remain  // -1 then return 0  if (thi == -1 || pol == -1)    return 0;  while (pol < n && thi < n) {    // can be caught    if (abs(pol - thi) <= k) {       pol = pol + 1;      while (pol < n && arr[pol] != 'P')        pol = pol + 1;       thi = thi + 1;      while (thi < n && arr[thi] != 'T')        thi = thi + 1;       res++;    }    // increment the current min(pol , thi) to    // the next policeman or thief found    else if (thi < pol) {      thi = thi + 1;      while (thi < n && arr[thi] != 'T')        thi = thi + 1;    }    else {      pol = pol + 1;      while (pol < n && arr[pol] != 'P')        pol = pol + 1;    }  }  return res;} int main(){  int k, n;  char arr1[] = { 'P', 'T', 'T', 'P', 'T' };  k = 2;  n = sizeof(arr1) / sizeof(arr1[0]);  cout << "Maximum thieves caught: " << policeThief(arr1, n, k) << endl;   char arr2[] = { 'T', 'T', 'P', 'P', 'T', 'P' };  k = 2;  n = sizeof(arr2) / sizeof(arr2[0]);  cout << "Maximum thieves caught: " << policeThief(arr2, n, k) << endl;   char arr3[] = { 'P', 'T', 'P', 'T', 'T', 'P' };  k = 3;  n = sizeof(arr3) / sizeof(arr3[0]);  cout << "Maximum thieves caught: " << policeThief(arr3, n, k) << endl;   return 0;} // This code is contributed by Aditya Kumar (adityakumar129)
// C program to find maximum number of thieves// caught#include <stdio.h>#include <math.h>#include <stdlib.h> // Returns maximum number of thieves that can// be caught.int policeThief(char arr[], int n, int k){  // Initialize the current lowest indices of  // policeman in pol and thief in thi variable as -1  int pol = -1, thi = -1, res = 0;   // Find the lowest index of policemen  for (int i = 0; i < n; i++) {    if (arr[i] == 'P') {      pol = i;      break;    }  }   // Find the lowest index of thief  for (int i = 0; i < n; i++) {    if (arr[i] == 'T') {      thi = i;      break;    }  }   // If lowest index of either policemen or thief remain  // -1 then return 0  if (thi == -1 || pol == -1)    return 0;  while (pol < n && thi < n) {    // can be caught    if (abs(pol - thi) <= k) {      pol = pol + 1;      while (pol < n && arr[pol] != 'P')        pol = pol + 1;       thi = thi + 1;      while (thi < n && arr[thi] != 'T')        thi = thi + 1;       res++;    }     // increment the current min(pol , thi) to    // the next policeman or thief found    else if (thi < pol) {      thi = thi + 1;      while (thi < n && arr[thi] != 'T')        thi = thi + 1;    }    else {      pol = pol + 1;      while (pol < n && arr[pol] != 'P')        pol = pol + 1;    }  }  return res;} // Driver Code Starts. int main(){  int k, n;   char arr1[] = { 'P', 'T', 'T', 'P', 'T' };  k = 2;  n = sizeof(arr1) / sizeof(arr1[0]);  printf("Maximum thieves caught: %d\n", policeThief(arr1, n, k));   char arr2[] = { 'T', 'T', 'P', 'P', 'T', 'P' };  k = 2;  n = sizeof(arr2) / sizeof(arr2[0]);  printf("Maximum thieves caught: %d\n", policeThief(arr2, n, k));   char arr3[] = { 'P', 'T', 'P', 'T', 'T', 'P' };  k = 3;  n = sizeof(arr3) / sizeof(arr3[0]);  printf("Maximum thieves caught: %d\n", policeThief(arr3, n, k));   return 0;} // This code is contributed by Aditya Kumar (adityakumar129)
// Java program to find maximum number of// thieves caughtimport java.io.*;import java.util.*; class GFG {     // Returns maximum number of thieves that can be caught.    static int policeThief(char arr[], int n, int k)    {        int pol = -1, thi = -1, res = 0;        // store the first index of police in pol        for (int i = 0; i < n; i++) {            if (arr[i] == 'P') {                pol = i;                break;            }        }         // store the first index of thief in thi        for (int i = 0; i < n; i++) {            if (arr[i] == 'T') {                thi = i;                break;            }        }         // return 0 if no police OR no thief found        if (thi == -1 || pol == -1)            return 0;        // loop to increase res iff distance between police        // and thief <= k        while (pol < n && thi < n) {            // thief can be caught            if (Math.abs(pol - thi) <= k) {                pol++;                // to find the index of next police for next                // iteration                while (pol < n && arr[pol] != 'P')                    pol++;                // to find the index of next thief for next                // iteration                thi = thi + 1;                while (thi < n && arr[thi] != 'T')                    thi++;                // increment res, as the thief has been                // caugh                res++;            }             // thief cannot be caught as dist > k            else if (thi < pol) {                // as index of thief is behind police, we                // need to find the next thief and check if                // it can be caught by the current police                // (it will be checked in the next                // iteration) Hence, find the index of next                // thief                thi++;                while (thi < n && arr[thi] != 'T')                    thi++;            }            else {                // as the index of police is behind the                // thief, it cannot catch the thief. Hence,                // we need the index of next police and                // check if it can catch the current thief                // (it will be checked in the next                // iteration)                pol++;                while (pol < n && arr[pol] != 'P')                    pol++;            }        }         return res;    }     // Driver code starts    public static void main(String[] args)    {         char arr1[] = { 'P', 'T', 'T', 'P', 'T' };        int n = arr1.length;        int k = 2;        System.out.println("Maximum thieves caught: " + policeThief(arr1, n, k));         char arr2[] = { 'T', 'T', 'P', 'P', 'T', 'P' };        n = arr2.length;        k = 2;        System.out.println("Maximum thieves caught: " + policeThief(arr2, n, k));         char arr3[] = { 'P', 'T', 'P', 'T', 'T', 'P' };        n = arr3.length;        k = 3;        System.out.println("Maximum thieves caught: " + policeThief(arr3, n, k));    }} // This code is contributed by Aditya Kumar (adityakumar129)
<script> // JavaScript program to find maximum number of thieves caught // Returns maximum number of thieves that can be caught.function policeThief(arr, n, k){   // Initialize the current lowest indices of  // policeman in pol and thief in thi variable as -1  let pol = -1, thi = -1, res = 0;     // Find the lowest index of policemen  for (let i = 0; i < n; i++) {    if (arr[i] == 'P') {      pol = i;      break;    }  }   // Find the lowest index of thief  for (let i = 0; i < n; i++) {    if (arr[i] == 'T') {      thi = i;      break;    }  }   // If lowest index of either policemen or thief remain  // -1 then return 0  if (thi == -1 || pol == -1)    return 0;  while (pol < n && thi < n)  {       // can be caught    if (Math.abs(pol - thi) <= k) {       pol = pol + 1;      while (pol < n && arr[pol] != 'P')        pol = pol + 1;       thi = thi + 1;      while (thi < n && arr[thi] != 'T')        thi = thi + 1;       res++;    }         // increment the current min(pol , thi) to    // the next policeman or thief found    else if (thi < pol) {      thi = thi + 1;      while (thi < n && arr[thi] != 'T')        thi = thi + 1;    }    else {      pol = pol + 1;      while (pol < n && arr[pol] != 'P')        pol = pol + 1;    }  }  return res;} // driver codelet k, n;let arr1 = [ 'P', 'T', 'T', 'P', 'T' ];k = 2;n = arr1.length;document.write("Maximum thieves caught: ",policeThief(arr1, n, k),"</br>"); let arr2 = [ 'T', 'T', 'P', 'P', 'T', 'P' ];k = 2;n = arr2.length;document.write("Maximum thieves caught: ",policeThief(arr2, n, k),"</br>"); let arr3 = [ 'P', 'T', 'P', 'T', 'T', 'P' ];k = 3;n = arr3.length;document.write("Maximum thieves caught: ",policeThief(arr3, n, k),"</br>"); // This code is contributed by shinjanpatra </script>
# Python program to find maximum number of thieves caught # Returns maximum number of thieves that can be caught.def policeThief(arr, n, k):     # Initialize the current lowest indices of    # policeman in pol and thief in thi variable as -1    pol,thi,res = -1,-1,0       # Find the lowest index of policemen    for i in range(n):        if (arr[i] == 'P'):            pol = i            break   # Find the lowest index of thief    for i in range(n):        if (arr[i] == 'T'):            thi = i            break     # If lowest index of either policemen or thief remain    # -1 then return 0    if (thi == -1 or pol == -1):        return 0    while (pol < n and thi < n):              # can be caught        if (abs(pol - thi) <= k):             pol = pol + 1            while (pol < n and arr[pol] != 'P'):                pol = pol + 1             thi = thi + 1            while (thi < n and arr[thi] != 'T'):                thi = thi + 1             res += 1             # increment the current min(pol , thi) to        # the next policeman or thief found        elif (thi < pol):            thi = thi + 1            while (thi < n and arr[thi] != 'T'):                thi = thi + 1        else:            pol = pol + 1            while (pol < n and arr[pol] != 'P'):                pol = pol + 1    return res # driver code arr1 = [ 'P', 'T', 'T', 'P', 'T' ];k = 2;n = len(arr1)print("Maximum thieves caught: " + str(policeThief(arr1, n, k))) arr2 = [ 'T', 'T', 'P', 'P', 'T', 'P' ];k = 2;n = len(arr2)print("Maximum thieves caught: "+ str(policeThief(arr2, n, k))) arr3 = [ 'P', 'T', 'P', 'T', 'T', 'P' ];k = 3;n = len(arr3)print("Maximum thieves caught: "+ str(policeThief(arr3, n, k))) # This code is contributed by shinjanpatra
Maximum thieves caught: 2
Maximum thieves caught: 3
Maximum thieves caught: 3
Time Complexity: O(N) Auxiliary Space: O(1)
This article is contributed by Satish Srinivas. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
jahid_nadim
sankalpvairat2
sandeepsingh27
harshjusharma
surindertarika1234
simmytarika5
surinderdawra388
adityakumar129
shinjanpatra
shruti456rawal
National Instruments
Greedy
National Instruments
Greedy
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Program for array rotation
Write a program to print all permutations of a given string
Coin Change | DP-7
Program for Shortest Job First (or SJF) CPU Scheduling | Set 1 (Non- preemptive)
Minimum Number of Platforms Required for a Railway/Bus Station
Dijkstra’s Algorithm for Adjacency List Representation | Greedy Algo-8
Difference between Prim's and Kruskal's algorithm for MST
3 Different ways to print Fibonacci series in Java
Minimize the maximum difference between the heights
Maximize difference between the Sum of the two halves of the Array after removal of N elements