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.
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++
#include <bits/stdc++.h>
using namespace std;
int policeThief( char arr[], int n, int k)
{
int res = 0;
vector< int > thi;
vector< int > pol;
for ( int i = 0; i < n; i++) {
if (arr[i] == 'P' )
pol.push_back(i);
else if (arr[i] == 'T' )
thi.push_back(i);
}
int l = 0, r = 0;
while (l < thi.size() && r < pol.size()) {
if ( abs (thi[l] - pol[r]) <= k) {
l++;
r++;
res++;
}
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;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int policeThief( char arr[], int n, int k)
{
int res = 0 ;
ArrayList<Integer> thi = new ArrayList<Integer>();
ArrayList<Integer> pol = new ArrayList<Integer>();
for ( int i = 0 ; i < n; i++) {
if (arr[i] == 'P' )
pol.add(i);
else if (arr[i] == 'T' )
thi.add(i);
}
int l = 0 , r = 0 ;
while (l < thi.size() && r < pol.size()) {
if (Math.abs(thi.get(l) - pol.get(r)) <= k) {
res++;
l++;
r++;
}
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));
}
}
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static int policeThief( char [] arr, int n, int k)
{
int res = 0;
List< int > thi = new List< int >();
List< int > pol = new List< int >();
for ( int i = 0; i < n; i++) {
if (arr[i] == 'P' )
pol.Add(i);
else if (arr[i] == 'T' )
thi.Add(i);
}
int l = 0, r = 0;
while (l < thi.Count && r < pol.Count) {
if (Math.Abs(thi[l] - pol[r]) <= k) {
l++;
r++;
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" );
}
}
|
Python3
def policeThief(arr, n, k):
i = 0
l = 0
r = 0
res = 0
thi = []
pol = []
while i < n:
if arr[i] = = 'P' :
pol.append(i)
elif arr[i] = = 'T' :
thi.append(i)
i + = 1
while l < len (thi) and r < len (pol):
if ( abs (thi[l] - pol[r]) < = k):
res + = 1
l + = 1
r + = 1
elif thi[l] < pol[r]:
l + = 1
else :
r + = 1
return res
if __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))))
|
Javascript
<script>
function policeThief(arr, n, k){
let i = 0
let l = 0
let r = 0
let res = 0
let thi = []
let pol = []
while (i < n){
if (arr[i] == 'P' )
pol.push(i)
else if (arr[i] == 'T' )
thi.push(i)
i += 1
}
while (l < thi.length && r < pol.length){
if (Math.abs( thi[l] - pol[r] ) <= k){
res += 1
l += 1
r += 1
}
else if (thi[l] < pol[r])
l += 1
else
r += 1
}
return res
}
let arr1 = [ 'P' , 'T' , 'T' , 'P' , 'T' ]
let k = 2
let 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>" )
</script>
|
Output
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 counter
- CASE 2: If the distance between the police and thief >= k, the current thief cannot be caught by the current police
- 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++
#include <bits/stdc++.h>
using namespace std;
int policeThief( char arr[], int n, int k)
{
int pol = -1, thi = -1, res = 0;
for ( int i = 0; i < n; i++) {
if (arr[i] == 'P' ) {
pol = i;
break ;
}
}
for ( int i = 0; i < n; i++) {
if (arr[i] == 'T' ) {
thi = i;
break ;
}
}
if (thi == -1 || pol == -1)
return 0;
while (pol < n && thi < n) {
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++;
}
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;
}
|
C
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int policeThief( char arr[], int n, int k)
{
int pol = -1, thi = -1, res = 0;
for ( int i = 0; i < n; i++) {
if (arr[i] == 'P' ) {
pol = i;
break ;
}
}
for ( int i = 0; i < n; i++) {
if (arr[i] == 'T' ) {
thi = i;
break ;
}
}
if (thi == -1 || pol == -1)
return 0;
while (pol < n && thi < n) {
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++;
}
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]);
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;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int policeThief( char arr[], int n, int k)
{
int pol = - 1 , thi = - 1 , res = 0 ;
for ( int i = 0 ; i < n; i++) {
if (arr[i] == 'P' ) {
pol = i;
break ;
}
}
for ( int i = 0 ; i < n; i++) {
if (arr[i] == 'T' ) {
thi = i;
break ;
}
}
if (thi == - 1 || pol == - 1 )
return 0 ;
while (pol < n && thi < n) {
if (Math.abs(pol - thi) <= k) {
pol++;
while (pol < n && arr[pol] != 'P' )
pol++;
thi = thi + 1 ;
while (thi < n && arr[thi] != 'T' )
thi++;
res++;
}
else if (thi < pol) {
thi++;
while (thi < n && arr[thi] != 'T' )
thi++;
}
else {
pol++;
while (pol < n && arr[pol] != 'P' )
pol++;
}
}
return res;
}
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));
}
}
|
Python3
def policeThief(arr, n, k):
pol, thi, res = - 1 , - 1 , 0
for i in range (n):
if (arr[i] = = 'P' ):
pol = i
break
for i in range (n):
if (arr[i] = = 'T' ):
thi = i
break
if (thi = = - 1 or pol = = - 1 ):
return 0
while (pol < n and thi < n):
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
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
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)))
|
C#
using System;
public class GFG {
static int policeThief( char [] arr, int n, int k)
{
int pol = -1, thi = -1, res = 0;
for ( int i = 0; i < n; i++) {
if (arr[i] == 'P' ) {
pol = i;
break ;
}
}
for ( int i = 0; i < n; i++) {
if (arr[i] == 'T' ) {
thi = i;
break ;
}
}
if (thi == -1 || pol == -1)
return 0;
while (pol < n && thi < n) {
if (Math.Abs(pol - thi) <= k) {
pol++;
while (pol < n && arr[pol] != 'P' )
pol++;
thi = thi + 1;
while (thi < n && arr[thi] != 'T' )
thi++;
res++;
}
else if (thi < pol) {
thi++;
while (thi < n && arr[thi] != 'T' )
thi++;
}
else {
pol++;
while (pol < n && arr[pol] != 'P' )
pol++;
}
}
return res;
}
static public void Main()
{
char [] arr1 = { 'P' , 'T' , 'T' , 'P' , 'T' };
int n = arr1.Length;
int k = 2;
Console.WriteLine( "Maximum thieves caught: "
+ policeThief(arr1, n, k));
char [] arr2 = { 'T' , 'T' , 'P' , 'P' , 'T' , 'P' };
n = arr2.Length;
k = 2;
Console.WriteLine( "Maximum thieves caught: "
+ policeThief(arr2, n, k));
char [] arr3 = { 'P' , 'T' , 'P' , 'T' , 'T' , 'P' };
n = arr3.Length;
k = 3;
Console.WriteLine( "Maximum thieves caught: "
+ policeThief(arr3, n, k));
}
}
|
Javascript
<script>
function policeThief(arr, n, k)
{
let pol = -1, thi = -1, res = 0;
for (let i = 0; i < n; i++) {
if (arr[i] == 'P' ) {
pol = i;
break ;
}
}
for (let i = 0; i < n; i++) {
if (arr[i] == 'T' ) {
thi = i;
break ;
}
}
if (thi == -1 || pol == -1)
return 0;
while (pol < n && thi < n)
{
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++;
}
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;
}
let 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>" );
</script>
|
Output
Maximum thieves caught: 2
Maximum thieves caught: 3
Maximum thieves caught: 3
Time Complexity: O(N)
Auxiliary Space: O(1)
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.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
27 Jan, 2023
Like Article
Save Article