📜  删除间隔后覆盖的最大点数

📅  最后修改于: 2021-04-24 21:42:50             🧑  作者: Mango

给定N个间隔,形式为[l,r]和整数Q。任务是找到一个间隔,该间隔在删除后会导致覆盖最大点数(所有其余间隔的并集)。请注意,所有给定的时间间隔仅覆盖1Q之间的数字。

例子:

方法:

  • 首先使用大小为n + 1的数组mark [] 。如果mark [i] = k ,这意味着恰好有k个间隔在其中包含点i
  • 维护计数,所有间隔所覆盖的总数。
  • 现在我们必须遍历所有间隔,并检查是否删除了每个间隔,然后从计数中删除了多少个数字。
  • 要在删除每个间隔后检查新计数,我们需要维护一个数组count1 [] ,其中count1 [i]告诉从1i的数字中有多少个正好出现一个间隔。
  • 任何间隔的新计数将为count –(count1 [r] – count1 [l-1]) 。由于只有那些恰好在一个间隔中出现并属于[l,r]的数字才必须从实际计数中排除。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
#define ll long long int
using namespace std;
  
// Function To find the required interval
void solve(int interval[][2], int N, int Q)
{
    int Mark[Q] = { 0 };
    for (int i = 0; i < N; i++) {
        int l = interval[i][0] - 1;
        int r = interval[i][1] - 1;
        for (int j = l; j <= r; j++)
            Mark[j]++;
    }
  
    // Total Count of covered numbers
    int count = 0;
    for (int i = 0; i < Q; i++) {
        if (Mark[i])
            count++;
    }
  
    // Array to store numbers that occur
    // exactly in one interval till ith interval
    int count1[Q] = { 0 };
    if (Mark[0] == 1)
        count1[0] = 1;
    for (int i = 1; i < Q; i++) {
        if (Mark[i] == 1)
            count1[i] = count1[i - 1] + 1;
        else
            count1[i] = count1[i - 1];
    }
  
    int maxindex;
    int maxcoverage = 0;
    for (int i = 0; i < N; i++) {
        int l = interval[i][0] - 1;
        int r = interval[i][1] - 1;
  
        // Calculate New count by removing all numbers
        // in range [l, r] occurring exactly once
        int elem1;
        if (l != 0)
            elem1 = count1[r] - count1[l - 1];
        else
            elem1 = count1[r];
        if (count - elem1 >= maxcoverage) {
            maxcoverage = count - elem1;
            maxindex = i;
        }
    }
    cout << "Maximum Coverage is " << maxcoverage
         << " after removing interval at index "
         << maxindex;
}
  
// Driver code
int main()
{
    int interval[][2] = { { 1, 4 },
                          { 4, 5 },
                          { 5, 6 },
                          { 6, 7 },
                          { 3, 5 } };
    int N = sizeof(interval) / sizeof(interval[0]);
    int Q = 7;
    solve(interval, N, Q);
  
    return 0;
}


Java
// Java implementation of the approach
  
class GFG 
{
  
// Function To find the required interval
static void solve(int interval[][], int N, int Q)
{
    int Mark[] = new int[Q];
    for (int i = 0; i < N; i++)
    {
        int l = interval[i][0] - 1;
        int r = interval[i][1] - 1;
        for (int j = l; j <= r; j++)
            Mark[j]++;
    }
  
    // Total Count of covered numbers
    int count = 0;
    for (int i = 0; i < Q; i++) 
    {
        if (Mark[i] != 0)
            count++;
    }
  
    // Array to store numbers that occur
    // exactly in one interval till ith interval
    int count1[] = new int[Q];
    if (Mark[0] == 1)
        count1[0] = 1;
    for (int i = 1; i < Q; i++)
    {
        if (Mark[i] == 1)
            count1[i] = count1[i - 1] + 1;
        else
            count1[i] = count1[i - 1];
    }
  
    int maxindex = 0;
    int maxcoverage = 0;
    for (int i = 0; i < N; i++) 
    {
        int l = interval[i][0] - 1;
        int r = interval[i][1] - 1;
  
        // Calculate New count by removing all numbers
        // in range [l, r] occurring exactly once
        int elem1;
        if (l != 0)
            elem1 = count1[r] - count1[l - 1];
        else
            elem1 = count1[r];
        if (count - elem1 >= maxcoverage)
        {
            maxcoverage = count - elem1;
            maxindex = i;
        }
    }
    System.out.println("Maximum Coverage is " + maxcoverage
        + " after removing interval at index "
        + maxindex);
}
  
// Driver code
public static void main(String[] args)
{
        int interval[][] = { { 1, 4 },
                        { 4, 5 },
                        { 5, 6 },
                        { 6, 7 },
                        { 3, 5 } };
    int N = interval.length;
    int Q = 7;
    solve(interval, N, Q);
}
}
  
/* This code contributed by PrinciRaj1992 */


Python3
# Python3 implementation of the approach
  
# Function To find the required interval
def solve(interval, N, Q):
  
    Mark = [0 for i in range(Q)]
    for i in range(N):
        l = interval[i][0] - 1
        r = interval[i][1] - 1
        for j in range(l, r + 1):
            Mark[j] += 1
      
    # Total Count of covered numbers
    count = 0
    for i in range(Q):
        if (Mark[i]):
            count += 1
  
    # Array to store numbers that occur
    # exactly in one interval till ith interval
    count1 = [0 for i in range(Q)]
    if (Mark[0] == 1):
        count1[0] = 1
    for i in range(1, Q):
        if (Mark[i] == 1):
            count1[i] = count1[i - 1] + 1
        else:
            count1[i] = count1[i - 1]
      
    maxindex = 0
    maxcoverage = 0
    for i in range(N):
        l = interval[i][0] - 1
        r = interval[i][1] - 1
  
        # Calculate New count by removing all numbers
        # in range [l, r] occurring exactly once
        elem1 = 0
        if (l != 0):
            elem1 = count1[r] - count1[l - 1]
        else:
            elem1 = count1[r]
        if (count - elem1 >= maxcoverage):
            maxcoverage = count - elem1
            maxindex = i
          
    print("Maximum Coverage is", maxcoverage, 
          "after removing interval at index", maxindex)
  
# Driver code
interval = [[ 1, 4 ],
            [ 4, 5 ],
            [ 5, 6 ],
            [ 6, 7 ],
            [ 3, 5 ]]
N = len(interval)
Q = 7
solve(interval, N, Q)
  
# This code is contributed by mohit kumar


C#
// C# implementation of the approach
using System;
  
class GFG 
{
  
// Function To find the required interval
static void solve(int[,] interval, int N, int Q)
{
    int[] Mark = new int[Q];
    for (int i = 0; i < N; i++)
    {
        int l = interval[i,0] - 1;
        int r = interval[i,1] - 1;
        for (int j = l; j <= r; j++)
            Mark[j]++;
    }
  
    // Total Count of covered numbers
    int count = 0;
    for (int i = 0; i < Q; i++) 
    {
        if (Mark[i] != 0)
            count++;
    }
  
    // Array to store numbers that occur
    // exactly in one interval till ith interval
    int[] count1 = new int[Q];
    if (Mark[0] == 1)
        count1[0] = 1;
    for (int i = 1; i < Q; i++)
    {
        if (Mark[i] == 1)
            count1[i] = count1[i - 1] + 1;
        else
            count1[i] = count1[i - 1];
    }
  
    int maxindex = 0;
    int maxcoverage = 0;
    for (int i = 0; i < N; i++) 
    {
        int l = interval[i,0] - 1;
        int r = interval[i,1] - 1;
  
        // Calculate New count by removing all numbers
        // in range [l, r] occurring exactly once
        int elem1;
        if (l != 0)
            elem1 = count1[r] - count1[l - 1];
        else
            elem1 = count1[r];
        if (count - elem1 >= maxcoverage)
        {
            maxcoverage = count - elem1;
            maxindex = i;
        }
    }
    Console.WriteLine("Maximum Coverage is " + maxcoverage
        + " after removing interval at index "
        + maxindex);
}
  
// Driver code
public static void Main()
{
    int[,] interval = { { 1, 4 },
                    { 4, 5 },
                    { 5, 6 },
                    { 6, 7 },
                    { 3, 5 } };
    int N = interval.Length;
      
    int Q = 7;
    solve(interval, N/2, Q);
}
}
  
/* This code contributed by Code_Mech */


输出:
Maximum Coverage is 7 after removing interval at index 4