【问题标题】:Complexity with Array.minArray.min 的复杂性
【发布时间】:2009-11-16 19:42:57
【问题描述】:

我有一个数组:

[0, 0, 0, 0, 0, 0, 0, 1, 2, 3]

我需要找出不为零的最小元素的索引。我该怎么做?

【问题讨论】:

  • 如果你的数组中有几个 1,你想得到什么?

标签: ruby arrays


【解决方案1】:

对于 ruby​​ 1.8.7+:

>> [0,0,2,0,1,3].each_with_index.reject {|(e, i)| e == 0}
=> [[2, 2], [1, 4], [3, 5]]
>> [0,0,2,0,1,3].each_with_index.reject {|(e, i)| e == 0}.min
=> [1, 4]
>> [0,0,2,0,1,3].each_with_index.reject {|(e, i)| e == 0}.min[1]
=> 4

对于 ruby​​ 1.8.6:

a.zip((0...a.size).to_a).reject {|(e, i)| e == 0}.min[1]

(卡盘解决方案)

【讨论】:

  • injectreject有什么区别?
  • @gmile:它们完全不相关。 inject 将数组减少为单个累加值,而 reject 返回不包含给定块返回 true 的对象的数组版本。
  • reject 删除满足特定条件的元素(好吧,实际上reject 返回一个包含原始数组中不满足条件的元素的数组——它实际上并不影响原始数组)。注入,这是完全不同的,它基本上通过对给定函数 f(块)和起始对象的数组的每个元素执行 obj = f(obj, element) 来创建一个对象。大多数其他可枚举操作都可以用注入来表示,但这并不意味着它们应该是;-)
  • 顺便说一下,这个实现有一个(IMO希望的)属性,如果最小值出现不止一次,它总是返回第一次出现。
  • 为了兼容 1.8.6,您应该能够将 each_with_index 调用替换为 zip((0...a.size).to_a)。总之,a.zip((0...a.size).to_a).reject {|(e, i)| e == 0}.min[1].
【解决方案2】:
a=[0, 0, 0, 0, 0, 0, 0, 1, 2, 3]
i=a.index a.reject{|x|x==0}.min

(i=7)

【讨论】:

    【解决方案3】:

    最简单的方法: 检查数组的每个元素,保留一个最小的变量,将其设置为等于您遇到的第一个数字(除非为 0,然后丢弃并使用下一个数字)。每当您遇到小于最小值的数字时,请将其设置为最小值。当然,丢弃任何零而不是设置最小值。

    更高效: 看起来我们有一个排序数组,如果我们可以利用它来发挥我们的优势,我们可以使用更好的搜索机制,例如快速搜索或二进制搜索。我将描述二进制搜索,因为它很容易理解。

    我们的数组是按升序排列的。 检查最中间的元素,将其设置为等于您的最小值(除非 0)。在这个中间元素上将数组分成两半。由于数组是升序的,所以检查左半部分的中点(除非元素为 0,然后检查右)。继续直到拆分时左边只有一个元素。这是你的最低要求。

    【讨论】:

    • +1:此过程比遍历数组、生成新数组、然后按照接受的答案中的建议在该数组上找到最小值要快。
    【解决方案4】:

    我不懂 Ruby,所以无法提供代码,但我立即想到的过程是:

    1. 创建数组的副本(如果需要)
    2. 删除所有0 条目
    3. 检查新数组中的最小值

    【讨论】:

    • 除非您添加第 4 步并返回原始数组并搜索您在第 3 步中找到的值,否则这将无法确定索引(在原始数组中)。这不是最有效的方法.
    猜你喜欢
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多