【问题标题】:Improving finding Min and Max in Array改进在数组中查找最小值和最大值
【发布时间】:2017-05-28 18:23:39
【问题描述】:

我的老师教我快速排序算法,它的成本约为 O(n)。在运行该排序之前,我必须找出数组中哪些元素是最大和最小的。

这是我的解决方案:

//n is a size of array a[]
for(int i = 0; i < n ; i++){
  if (_max < a[i]) _max = a[i];
  if (_min > a[i]) _min = a[i];
}

让 f(n) 是该 for 循环中的条件运算符的数量(比较变量 i 除外)。所以它的成本:

  • n 次比较 _max 和 a[i]
  • n 时间比较 _min 和 a[i]

所以,f(n) = 2n。

我的朋友写了这样的代码:

for(int i = 0; i < n-1; i+=2)
  if (a[i] < a[i+1]){
    if (_max < a[i+1]) _max = a[i+1];
    if (_min > a[i]) _min = a[i];
  }
  else{
    if (_max < a[i]) _max = a[i];
      if (_min > a[i+1]) _min = a[i+1];
  }
// Compare one more time if n is odd
if (n % 2 == 1){
  if (_min > a[n-1]) _min = a[n-1];
  if (_max < a[n-1]) _max = a[n-1];
}

我们可以很容易地得到 f'(n) = 3n/2 + 3。当 n 足够大时,似乎 f'(n)

但我的老师要求 f(n) = n 或 f(n) = n + a,其中 a 是一个 const。

有什么想法吗?

【问题讨论】:

  • 在第一个 if 子句中使用 else 可以稍微加快您的解决方案。但主要是学习O-notation,它告诉你忽略常数因子,见stackoverflow.com/questions/487258/…
  • @Gerriet 你能描述更多吗?我的老师想计算for循环中有多少操作,而不仅仅是big-O :D
  • 阅读我在第一条评论中添加的链接,或许可以考虑寻找更好的老师...
  • 另外:在这个stackoverflow.com/questions/16764207/… 中,两种变体都得到了更详细的讨论。
  • hm... 我认为运行时间在这里并不重要。我的老师只想减少 for-loop min-max 中的操作。换句话说,有没有使用 1 个 for 循环(包括 1 个 if-else)来找出最小值和最大值的解决方案?

标签: algorithm sorting max min


【解决方案1】:

没有。在 n(或 n+a) 次比较中,不可能同时找到最大值和最小值。它至少需要 3n/2 - 2 次比较。请参阅 this proofthis proof。也许你可以把这些证明给你的老师看……

关于这个序列还有其他提示吗?像它是均匀分布的还是这样的?

【讨论】:

  • 没有关于序列的提示。这就是我必须找到的!非常感谢!
【解决方案2】:

n 很大时,f'(n) = f(n),因为两者的时间复杂度都是 O(n)。

但是,您似乎需要一次找到最小值和最大值,因此您的算法时间复杂度为 O(n) 是可以的,因为 Flash 排序的成本也是 O(n),因此总体时间复杂度将由O(n)。

换句话说:

OverallTime = FindMinMax + FlashSort
OverallTime = O(n) + O(n)
OverallTime = 2*O(n)
OverallTime = O(n)

即使 FindMinMax 更快,Flash Sort 的第二项仍然会支配整体时间复杂度。


如果您必须更快地做到这一点,您可以构建一个名为 Segment Tree 的数据结构,它:

使用 O(n log n) 存储并且可以在 O(n log n) 时间内构建。部分 树支持搜索包含查询的所有区间 点 O(log n + k),k 是检索到的间隔数或 段。

【讨论】:

  • 在本节中,我的老师不关心 big-O 中的时间复杂度。他要求我们改进 for 循环以找出数组中的最小和最大元素。换句话说,我只需要减少 f(n)。
猜你喜欢
  • 2018-05-03
  • 2017-08-18
  • 2021-09-15
  • 2018-08-01
  • 2019-03-31
  • 2016-11-12
  • 1970-01-01
  • 2016-06-06
相关资源
最近更新 更多