【问题标题】:Length of minimum subsequence that spans entire length of array?跨越整个数组长度的最小子序列的长度?
【发布时间】:2019-09-14 12:26:44
【问题描述】:

我得到一个长度为 N 的整数数组,其中的元素表示它可以覆盖的跨度从 0 到 N-1。所以对于元素 a[i],元素的范围从 max(i-a[i],0) 到 min(i+a[i],N-1)。

如何求跨越整个空间的最小子序列的长度即从0到N-1;

示例:对于这个数组 [1,1,1,3,2,1,1,4],答案应该是 2

这是我到目前为止所得到的,它并不适用于所有情况

int arr[] = {2,2,1,3,2,1,1,4,1,1,1,1,1,1,1,1,1,1}; // Fails for this case
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        int[] sortedIndices = IntStream.range(0, arr.length)
                .boxed().sorted((i, j) -> span(arr[j],j,arr.length) - span(arr[i],i,arr.length))
                .mapToInt(ele -> ele).toArray();

        int i=0;
        int ans = 0;
        while (min>0 || max<arr.length-1) {
            int ind = sortedIndices[i++];
            int val = arr[ind];

            int tmin = Math.max(0,ind-val);
            int tmax = Math.min(arr.length - 1, ind+val);
            if(tmin < min || tmax > max)
                ans++;

            min = Math.min(min, tmin);
            max = Math.max(max, tmax);
        }

        System.out.println(ans);

【问题讨论】:

  • 第一个示例的答案 2 是如何得到的?我看到 4(索引范围 3..6)
  • 您至少需要两个元素来覆盖整个跨度,例如元素 3 和 4 分别位于数组中的 3 和 7 处。
  • 所以你真的不需要子数组(连续)而是子序列。所以这是set cover problem
  • 感谢指正!将进行编辑以提高清晰度。不知道设置封面问题,会调查它

标签: arrays algorithm range sub-array


【解决方案1】:

看来这个问题可以用简单的贪心算法解决。

为每个数组条目创建带有 startfinish 字段的区间 (a[i].start = i-arr[i] etc)

按起始字段对区间进行排序。

在覆盖0的那些中找到最右边finish的区间,使maxx=a[i].finish

扫描start0..maxx范围内的间隔,选择最右边的finish

继续。

快速制作的 Python 实现(可能需要更多检查)

ar = [2,2,1,3,2,1,4,4]
n = len(ar)
a = [(max(0, i-ar[i]), min(i+ar[i], n-1)) for i in range(n)]
print(ar)
a.sort()
print(a)
cnt = 0
maxx = -1
left = 0
i = 0
while i < n and maxx < n - 1:
    while i < n and a[i][0] <= left and maxx < n - 1:
        maxx = max(a[i][1], maxx)
        i+=1
    print("maxx ", maxx)
    left = maxx
    cnt += 1

print("cover ", cnt)

[2, 2, 1, 3, 2, 1, 4, 4]
[(0, 2), (0, 3), (0, 6), (1, 3), (2, 6), (2, 7), (3, 7), (4, 6)]
maxx  6
maxx  7
cover  2

【讨论】:

  • 在覆盖 0 的项目中,最右边的边框 6 用于 arr[3]。在覆盖 6 个(从 1 到 6)的项目中,最右边的边框是 arr[6] 或 arr[7],所以 count 是 2
猜你喜欢
  • 2018-02-19
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
  • 2016-06-16
  • 2020-09-19
  • 1970-01-01
  • 2014-08-26
  • 2022-01-05
相关资源
最近更新 更多