📜  警察抓小偷

📅  最后修改于: 2021-05-04 17:14:03             🧑  作者: Mango

给定大小为n的数组,该数组具有以下规范:

  1. 数组中的每个元素都包含一个警察或一个小偷。
  2. 每个警察只能抓一个小偷。
  3. 警察不能抓住距离警察超过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个错误的消息。可以应用对称参数来表明从数组的右侧遍历这些对象也失败。我们可以观察到,无论
警察并只关注分配工作:

1.得出警察p和小偷t的最低索引。分配
如果| pt | <= 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`


输出:

Maximum thieves caught: 2
Maximum thieves caught: 3
Maximum thieves caught: 3


时间复杂度: O(N)
辅助空间: O(N)