📌  相关文章
📜  所需的最小整数数,以便每个 Segment 至少包含其中一个

📅  最后修改于: 2021-10-26 06:35:49             🧑  作者: Mango

给定两个数组start[]end[]由分别表示段的起点和终点的正整数组成,任务是找到位于至少一个给定段中的最小整数数,并且每个段包含在至少其中之一。

例子:

数学公式:
描述问题的数学方法是将每个给定的整数范围视为由一条线上的两个整数坐标[a i , b i ] 定义的线段。那么覆盖每个给定范围所需的最小整数数是使每个段至少包含一个点的最小点数。
示例 1的表示如下所示:

幼稚的方法:
解决问题的最简单方法是找到所有段的所有起点的最小值和所有终点的最大值。迭代这个范围,并为这个范围内的每个点跟踪可以使用这个点覆盖的段数。使用数组将段数存储为:

arr[point] = 使用该点可以覆盖的段数

  1. 查找数组arr[] 中的最大值。
  2. 如果该最大值等于N,则该值对应的索引是覆盖所有段的点。
  3. 如果该最大值小于N ,则该值对应的索引是覆盖某些段的点。
  4. 对数组 arr[] 重复步骤 1 到 3,不包括此最大值,直到找到的所有最大值的总和等于 N。

时间复杂度: O((A-B+1)*N),其中A是线段终点的最大值,B是线段起点的最小值。
辅助空间: O(1)

有效的方法:
使用贪婪技术可以有效地解决该问题。请按照以下步骤解决问题:

  • 端点对段进行排序
  • 选择所有线段最小终点对应的点(或坐标)。
  • 现在,所有起点小于该选定点且终点大于该选定点的线段都可以被该点覆盖
  • 然后打印最小点数。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// function to sort the 2D vector
// on basis of second element.
bool sortcol(const pair p1,
             const pair p2)
{
    return p1.second < p2.second;
}
 
// Function to compute minimum number
// of points which cover all segments
void minPoints(pair points[], int n)
{
     
    // Sort the list of tuples by
    // their second element.
    sort(points, points + n, sortcol);
 
    // To store the solution
    vector coordinates;
    int i = 0;
 
    // Iterate over all the segments
    while (i < n)
    {
        int seg = points[i].second;
        coordinates.push_back(seg);
        int p = i + 1;
 
        if (p >= n)
            break;
 
        // Get the start point of next segment
        int arrived = points[p].first;
 
        // Loop over all those segments whose
        // start point is less than the end
        // point of current segment
        while (seg >= arrived)
        {
            p += 1;
 
            if (p >= n)
                break;
 
            arrived = points[p].first;
        }
        i = p;
    }
     
    // Print the possibles values of M
    for(auto point : coordinates)
        cout << point << " ";
}
 
// Driver code
int main()
{
    int n = 4;
 
    // Starting points of segments
    int start[] = { 4, 1, 2, 5 };
 
    // Ending points of segments
    int end[] = { 7, 3, 5, 6 };
 
    pair points[n];
 
    // Insert ranges in points[]
    for(int i = 0; i < n; i++)
    {
        points[i] = { start[i], end[i] };
    }
 
    // Function call
    minPoints(points, n);
 
    return 0;
}
 
// This code is contributed by Kingash


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
     
// Function to compute minimum number
// of points which cover all segments
static void minPoints(int[][] points, int n)
{
     
    // Sort the list of tuples by
    // their second element.
    Arrays.sort(points, (a, b) -> a[1] - b[1]);
 
    // To store the solution
    ArrayList coordinates = new ArrayList<>();
    int i = 0;
 
    // Iterate over all the segments
    while (i < n)
    {
        int seg = points[i][1];
        coordinates.add(seg);
        int p = i + 1;
 
        if (p >= n)
            break;
 
        // Get the start point of next segment
        int arrived = points[p][0];
 
        // Loop over all those segments whose
        // start point is less than the end
        // point of current segment
        while (seg >= arrived)
        {
            p += 1;
             
            if (p >= n)
                break;
                 
            arrived = points[p][0];
        }
        i = p;
    }
 
    // Print the possibles values of M
    for(Integer point : coordinates)
        System.out.print(point + " ");
}
 
// Driver code
public static void main(String[] args)
{
 
    int n = 4;
 
    // Starting points of segments
    int[] start = { 4, 1, 2, 5 };
 
    // Ending points of segments
    int[] end = { 7, 3, 5, 6 };
 
    int[][] points = new int[n][2];
 
    // Insert ranges in points[]
    for(int i = 0; i < n; i++)
    {
        points[i][0] = start[i];
        points[i][1] = end[i];
    }
 
    // Function call
    minPoints(points, n);
}
}
 
// This code is contributed by offbeat


Python3
# Python3 program for the above approach
 
# Function to compute minimum number
# of points which cover all segments
def minPoints(points):
 
    # Sort the list of tuples by
    # their second element.
    points.sort(key = lambda x: x[1])
 
    # To store the solution
    coordinates = []
    i = 0
 
    # Iterate over all the segments
    while i < n:
 
        seg = points[i][1]
        coordinates.append(seg)
        p = i + 1
 
        if p >= n:
            break
 
        # Get the start point of next segment
        arrived = points[p][0]
 
        # Loop over all those segments whose
        # start point is less than the end
        # point of current segment
        while seg >= arrived:
 
            p += 1
            if p >= n:
                break
            arrived = points[p][0]
        i = p
 
# Print the possibles values of M
    for point in coordinates:
        print(point, end =" ")
 
 
# Driver Code
n = 4
 
# Starting points of segments
start = [4, 1, 2, 5]
 
# Ending points of segments
end = [7, 3, 5, 6]
 
points = []
 
# Insert ranges in points[]
for i in range(n):
    tu = (start[i], end[i])
    points.append(tu)
 
# Function Call
minPoints(points)


输出:
3 6

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

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程