Algorithm 不超过覆盖范围限制的最大间隔子集?

Algorithm 不超过覆盖范围限制的最大间隔子集?,algorithm,intervals,Algorithm,Intervals,这里有一个我很困惑的编码问题 给定一个二维数组[[1,9],[2,8],[2,5],[3,4],[6,7],[6,8]],每个内部数组表示一个间隔;如果我们把这些间隔堆积起来,我们会看到: 1 2 3 4 5 6 7 8 9 2 3 4 5 6 7 8 2 3 4 5 3 4 6 7 6 7 8 现在有一个限制,保险范围应该是我希望我正确理解了这个问题。这是我能用C#得到的解决方案: //测试 int[]grid={new int

这里有一个我很困惑的编码问题

给定一个二维数组
[[1,9],[2,8],[2,5],[3,4],[6,7],[6,8]]
,每个内部数组表示一个间隔;如果我们把这些间隔堆积起来,我们会看到:

1 2 3 4 5 6 7 8 9
  2 3 4 5 6 7 8
  2 3 4 5 
    3 4   
          6 7
          6 7 8

现在有一个限制,保险范围应该是我希望我正确理解了这个问题。这是我能用C#得到的解决方案:

//测试
int[]grid={new int[]{1,9},new int[]{2,8},new int[]{2,5},new int[]{3,4},new int[]{6,7},new int[]{6,8};
水下指示器sf=新水下指示器(网格);
int t1=sf.getNumberOfInterval(1)//6.
INTT2=sf.GetNumberOfInterval(2)//5.
int t3=sf.GetNumberOfInterval(3)//5.
int t4=sf.GetNumberOfInterval(4)//2.
int t5=sf.GetNumberOfInterval(5)//0
类子索引
{
词典;
整数间隔计数;
公共子索引(int[][]网格)
{
init(网格);
}
私有void init(int[][]网格)
{
this.dic=新字典();
this.intervalCount=grid.Length;
for(int r=0;r对于(int i=start;i我认为您可以使用扫描算法解决此问题。以下是我的方法:

一般的想法是,我们不会找出您可以选择的最大间隔数,并且仍然符合限制,而是找出必须删除的最小间隔数,以使所有数字符合限制。我们可以这样做:

首先创建一个三元组向量,第一部分是整数,第二部分是布尔值,第三部分是整数。第一部分表示输入的所有数字(间隔的
开始
结束
),第二部分告诉我们第一部分是间隔的开始还是结束,而第三部分表示间隔的
id

根据第一部分对创建的向量进行排序,如果出现平局,
开始
应位于某些间隔的
结束
之前

在您提供的示例中,向量将为:

1,0
2,0
2,0
2,0
3,0
4,1
5,1
6.0
7,1
8,1
8,1
9,1

现在,在向量上迭代,同时保留一组整数,这些整数表示当前采用的间隔。集合中的数字表示当前采用的间隔的
结束时间
。该集合应按递增顺序排序

在向量上迭代时,我们可能会遇到以下两种可能性之一:

  • 我们目前正在处理区间的
    开始
    。在这种情况下,我们只需添加该区间的
    结束
    (由第三部分
    id
    标识)对于集合。如果集合的大小超过限制,我们必须准确地删除一个间隔,但哪个间隔最适合删除?当然,它是具有最大
    结束
    的间隔,因为删除此间隔不仅可以帮助您减少所采取的间隔数,以满足限制,而且也将非常有帮助ful,因为它持续时间最长。只需从集合中删除此间隔(相应的
    结束
    将是集合中的最后一个,因为集合按
    结束
    的递增顺序排序)

  • 我们当前正在处理一个区间的
    end
    ,在本例中,请检查集合。如果它包含指定的
    end
    ,请删除它,因为相应的区间已经结束。如果集合不包含与我们正在处理的区间相匹配的
    end
    ,只需继续迭代到下一个区间即可元素,因为这意味着我们已经决定不采用相应的间隔

  • 如果您需要计算所用间隔的数量,甚至打印它们,这是很容易的。每当您处理间隔的
    end
    ,并且您实际在集合中发现该
    end
    ,这意味着相应的间隔是一个已用间隔,您可以将答案增加1,打印它或将其保留在某个向量中提出你的答案


    我的方法的总体复杂性是:N Log(N),其中N是输入中给定的区间数。

    为了澄清,准确地说:您正在寻找满足“对于你们所有的问题,答案是:是的;你们所有的理解都正是我的意思。谢谢!
                    //test
                    int[][] grid =  { new int[]{ 1, 9 }, new int[] { 2, 8 }, new int[] { 2, 5 }, new int[] { 3, 4 }, new int[] { 6, 7 }, new int[] { 6, 8 } };
                    SubsetFinder sf = new SubsetFinder(grid);
                    int t1 = sf.GetNumberOfIntervals(1);//6
                    int t2 = sf.GetNumberOfIntervals(2);//5
                    int t3 = sf.GetNumberOfIntervals(3);//5
                    int t4 = sf.GetNumberOfIntervals(4);//2
                    int t5 = sf.GetNumberOfIntervals(5);//0
    
    
            class SubsetFinder
            {
                Dictionary<int, List<int>> dic;
                int intervalCount;
                public SubsetFinder(int[][] grid)
                {
                    init(grid);
                }
                private void init(int[][] grid)
                {
                    this.dic = new Dictionary<int, List<int>>();
                    this.intervalCount = grid.Length;
                    for (int r = 0; r < grid.Length; r++)
                    {
                        int[] row = grid[r];
                        if (row.Length != 2) throw new Exception("not grid");
                        int start = row[0];
                        int end = row[1];
                        if (end < start) throw new Exception("bad interval");
                        for (int i = start; i <= end; i++)
                            if (!dic.ContainsKey(i))
                                dic.Add(i, new List<int>(new int[] { r }));
                            else
                                dic[i].Add(r);
                    }
                }
                public int GetNumberOfIntervals(int coverageLimit)
                {
                    HashSet<int> hsExclude = new HashSet<int>();
                    foreach (int key in dic.Keys)
                    {
                        List<int> lst = dic[key];
                        if (lst.Count < coverageLimit)
                            foreach (int i in lst)
                                hsExclude.Add(i);
                    }
                    return intervalCount - hsExclude.Count;
                }
            }