【问题标题】:Finding smallest subsequence of an array查找数组的最小子序列
【发布时间】:2017-03-21 08:04:20
【问题描述】:

我有一个数组,例如{1,2,4,5,6}。我希望我的函数找到最大可能的数字 X 使得 1,2,...,X-1 中的所有数字都在数组中。在这种情况下,X=3。数组中的数字可以从 0 到无穷大。

我的尝试是:

int array(int* t, int r) {
    int* a;
    int m=0;
    int i;

    for(i=0;i<=r;i++){
        a[i]=i;
        if(a[i]==t[i])
            m++;
    }
    return m;
}

我想创建一个从 1 到 r 的数组,这是一个数组的长度,充满自然数,即 {1,2,3...} 。然后我想将它与实际的数组 t 进行比较。如果有匹配的,请寻找另一个。

我不知道为什么它不起作用以及如何解决它?

无论如何代码都不起作用,我仍然不知道如何解决这个问题。

仍在寻找答案。

更新:我做了类似的事情:

int array(int* t, int r) {

for(int x=0;x<r;x++){

    for(int y=0; y<r-1;y++){
        if(t[y]>t[y+1]){
            int temp=t[y+1];
            t[y+1]=t[y];
            t[y]=temp;
        }
    }
}
   for (int i = 0; i != r; i++) {
        if (t[i] != (i + 1)) {
            return i + 1;
        }
    }
    return r + 1;
}

但是,当在输入数组中我在某个地方为零时,例如{5,0,1,2} 函数总是返回 1,不管 0 放在哪里。这是为什么呢?

【问题讨论】:

  • 数组索引从零开始。修改您的 for 循环,使其变为:for(i=0;i stackoverflow.com/questions/4108313/…
  • a 未初始化(顺便说一句,不需要)。
  • 还是不行。移动了“*”还是不行
  • 您的算法完全错误。只有当这些数字占据数组中最左边的位置并且按排序顺序时,它才会起作用。您想要一个缓慢但简单的解决方案,还是一个快速但复杂的解决方案?
  • 您是否在进行桶排序,使用大量内存来获得快速运行时间?您忘记初始化 a,因此您试图将数字存储在内存中未定义的随机位置。如果这是您的计划,那么您需要有两个循环,一个用于构建查找,另一个用于获取答案。

标签: c++ arrays algorithm loops


【解决方案1】:

你不需要额外的数组,你可以迭代直到索引不符合你的期望:

int find_iota_end(const int* a, int size)
{
    std::sort(a, a + size); // if initial array is not sorted.
    for (int i = 0; i != size; ++i) {
        if (a[i] != (i + 1)) {
            return i + 1;
        }
    }
    return size + 1;
}

【讨论】:

  • 对于数组 {1,5,6,2,3} 和 size=5,此函数返回 2 而它应该返回 4。
  • 不清楚数组没有排序,std::sort(a, a + size); 会解决这个问题。
【解决方案2】:

您的代码存在许多问题

int array(int* t, int r) {
    int* a;
    int m=0;
    int i;

    for(i=0;i<=r;i++){
        a[i]=i;
        if(a[i]==t[i])
            m++;
    }
    return m;
}
  • a 未初始化,即它不指向您的程序分配的有效内存。你需要做int *a = new int[r]在你的函数返回之前不要忘记delete a
  • i 应该上升到 r - 1 而不是 r。所以i &lt; r 而不是i &lt;= r

这里有一些伪代码概述了解决这个问题的可能方法。如果找不到有效的起始范围,则结果为零。

伪代码(快速,感谢Kenny Ostrom

  • curr = 0
  • lookup = std::unordered_set&lt;int&gt;
  • 将所有元素插入lookup
  • 0n,其中n 是元素数组的大小
    • [循环]
      • 如果curr + 1 不在lookup 中,则跳出循环
      • 否则将curr 设置为curr + 1
    • [循环结束]
  • 终于返回curr + 1

伪代码(有点快,取决于您的排序算法)

  • 对数组进行排序(std::sort 始终是一个不错的选择)
  • 将一些变量curr设置为0
  • 从 a0 到 an,其中 ai 是数组中索引 i处的元素>
    • [循环]
      • 如果curr + 1 不等于ai 则跳出循环
      • 否则将curr 设置为ai
    • [循环结束]
  • 终于返回curr + 1

伪代码(慢)

  • 将一些变量curr设置为0
  • 从 a0 到 an,其中 ai 是数组中索引 i处的元素>

    • [循环]
      • 从aj 到an 其中j = 0
        • [循环]
          • 如果 curr + 1 等于 aj 则将 curr 设置为 aj 并跳出此循环
        • [循环结束]
        • 如果curr没有改变,则跳出这个循环
    • [循环结束]
  • 终于返回curr + 1

【讨论】:

  • 为什么 a in 未初始化?如果它以与 t 相同的方式初始化?
  • @vforbiedronka 它未初始化,因为您没有使它等于任何东西。要初始化它,您需要创建一个新数组并将a 设置为指向该数组,或者将a 设置为指向一个已创建的数组。
  • @vforbiedronka 最好是int *a = new int[/*Enter the size you want here*/]。查看我的更新答案
  • 我将把我的伪代码扔在这里,因为你已经涵盖了错误。 std::set 查找;对于输入数组中的所有数字,lookup.insert(number);在查找、递增或返回答案中查找 answer = 1。 (做一个桶式查找表的问题是你的空间取决于答案的值,而不是输入的大小,你必须能够增长它)
  • 我的意思是无序集,我的错。使用 std::set 并没有真正比排序有任何优势。您的二次搜索在伪代码中有一个小错误,请考虑 {2, 1, 4}。
【解决方案3】:

经过反思,我认为你最初的想法非常接近一个好的算法,如果你修复错误,并完全忽略任何值 a[i] 值不在 [1..r] 范围内。

您必须为第二个向量分配实际内存,并且需要两个独立的循环。如果值相关,则第一个循环填充第二个向量。第二个循环寻找答案。

这给你空间 O(n) 因为你只考虑那么多可能的答案,而时间 O(n) 因为它只是读取长度两次。

【讨论】:

    猜你喜欢
    • 2014-10-31
    • 1970-01-01
    • 2014-11-15
    • 2018-09-10
    • 2020-05-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 2019-02-13
    相关资源
    最近更新 更多