给定一个大小为 n 的数组,其规格如下:
- 数组中的每个元素都包含一个警察或一个小偷。
- 每个警察只能抓到一个小偷。
- 警察无法抓住距离警察超过 K 个单位的小偷。
我们需要找到可以抓住的最大盗贼数量。
例子:
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.
一种蛮力方法是检查所有可行的警察和小偷组合集,并返回其中的最大大小集。它的时间复杂度是指数级的,如果我们观察到一个重要的属性,它可以被优化。
一个有效的解决方案是使用贪心算法。但是哪个贪婪的财产
使用可能会很棘手。我们可以尝试使用:“对于左边的每个警察,抓住最近的可能的小偷。”这适用于上面给出的示例三,但由于输出不正确的 2 而失败,例如 2。
我们也可以尝试:“对于左边的每个警察,抓住尽可能远的小偷”。这适用于上面给出的示例二,但由于输出不正确的 2 而失败,例如三。可以应用对称参数来表明从数组右侧遍历这些也失败。我们可以观察到这种思考不考虑
警察并专注于分配工作:
1. 得到警察 p 和小偷 t 的最低指数。进行分配
如果|点| <= k 并递增到下一个找到的 p 和 t。
2. 否则增加 min(p, t) 到下一个找到的 p 或 t。
3. 重复以上两步,直到找到下一个 p 和 t。
4. 返回分配的数量。
下面是上述算法的实现。它使用向量来
将警察和小偷的索引存储在数组中并进行处理。
C++
// C++ program to find maximum number of thieves
// caught
#include
#include
#include
using namespace std;
// Returns maximum number of thieves that can
// be caught.
int policeThief(char arr[], int n, int k)
{
int res = 0;
vector thi;
vector 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++;
l++;
r++;
}
// increment the minimum index
else if (thi[l] < pol[r])
l++;
else
r++;
}
return res;
}
// Driver program
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
// Java program to find maximum number of
// thieves caught
import 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 thi = new ArrayList();
ArrayList pol = new ArrayList();
// 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++;
l++;
r++;
}
// increment the minimum index
else if (thi.get(l) < pol.get(r))
l++;
else
r++;
}
return res;
}
// Driver program
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 Danish kaleem */
Python3
# 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 program
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))))
# This code is contributed by `jahid_nadim`
Java
// Java program to find maximum number of
// thieves caught
import 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("Maximun thieves caught: "
+ policeThief(arr1, n, k));
char arr2[] = { 'T', 'T', 'P', 'P', 'T', 'P' };
n = arr2.length;
k = 2;
System.out.println("Maximun thieves caught: "
+ policeThief(arr2, n, k));
char arr3[] = { 'P', 'T', 'P', 'T', 'T', 'P' };
n = arr3.length;
k = 3;
System.out.println("Maximun thieves caught: "
+ policeThief(arr3, n, k));
}
}
// Driver code ends
C++
// C++ program to find maximum number of thieves
// caught
#include
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;
}
// Driver Code Starts.
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;
}
// Driver Code Ends
Maximum thieves caught: 2
Maximum thieves caught: 3
Maximum thieves caught: 3
时间复杂度: O(N)
辅助空间: O(N)
以下方法适用于 O(1) 空间复杂度
方法:
这种方法采取以下步骤:
- 首先找到最左边的警察和小偷并存储索引。可能有两种情况:
- 案例1:如果警察和小偷之间的距离<= k(给定),小偷可以被抓住,所以增加res计数器
- CASE 2:如果警察和小偷之间的距离>=k,当前小偷不能被当前警察抓到
- 对于CASE 2 ,如果警察在小偷后面,我们需要找到下一个警察并检查它是否能抓住当前的小偷。
- 如果小偷在警察后面,我们需要找到下一个小偷并检查当前警察是否可以抓住小偷
- 重复这个过程,直到我们找到下一个警察和小偷对,如果满足条件,即增加结果计数器,即CASE 1。
算法:
1. 将 pol 中的警察和 thi 变量中的小偷的当前最低索引初始化为 -1。
2 找出指数最低的警察和小偷。
3 如果警察或小偷的最低指数保持 -1,则返回 0。
4 如果 |pol – 这个 | <=k 然后分配并找到下一个警察和小偷。
5 否则将 min(pol , thi) 增加到下一个找到的警察或小偷。
6 重复以上两步,直到找到下一个警察和小偷。
7 返回分配的数量。
下面是上述算法的实现。
Java
// Java program to find maximum number of
// thieves caught
import 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("Maximun thieves caught: "
+ policeThief(arr1, n, k));
char arr2[] = { 'T', 'T', 'P', 'P', 'T', 'P' };
n = arr2.length;
k = 2;
System.out.println("Maximun thieves caught: "
+ policeThief(arr2, n, k));
char arr3[] = { 'P', 'T', 'P', 'T', 'T', 'P' };
n = arr3.length;
k = 3;
System.out.println("Maximun thieves caught: "
+ policeThief(arr3, n, k));
}
}
// Driver code ends
C++
// C++ program to find maximum number of thieves
// caught
#include
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;
}
// Driver Code Starts.
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;
}
// Driver Code Ends
Maximun thieves caught: 2
Maximun thieves caught: 3
Maximun thieves caught: 3
时间复杂度: O(N)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。