【问题标题】:Find elements missing from an array of ordered numbers从有序数字数组中查找缺失的元素
【发布时间】:2016-05-05 05:33:25
【问题描述】:

我有一个数组array 排序的数字。我从array 定义了一个数字e missing 如果:

  • 对于array 的某些元素vev + 1v - 1
  • e 不是 array 的元素,并且
  • e 不小于0

例如,缺少的元素:

array = [0, 1, 2, 4, 5, 6, 9, 10, 12, 13, 17]

是:

[3, 7, 8, 11, 14, 16, 18]

如何找到给定数组array 中缺少的元素?

【问题讨论】:

    标签: arrays ruby


    【解决方案1】:

    看起来你想要这样的东西:

    array = [0, 1, 2, 4, 5, 6, 9, 10, 12, 13, 17]
    possible_missing = array.flat_map {|e| [e-1, e+1]}.uniq
    #=> [1, 0, 2, 3, 5, 4, 6, 7, 8, 10, 9, 11, 13, 12, 14, 16, 18]
    diff = (possible_missing - array).select {|e| e >= 0}
    #=> [3, 7, 8, 11, 14, 16, 18]
    

    【讨论】:

    • 考虑使用- [-1] 而不是重度O(N) select >= 0。此外,[e-1, e+1]flat_map 内部就足够了。
    • @mudasobwa,我同意[e-1, e+1]。关于索引而不是选择 - 如果数组第一个元素不是0,情况会怎样?
    • 请问?可能出现在结果数组中的唯一多余元素是-1。也就是说,- [-1]select { |e| e >= 0 } 完全等效arr.flat_map { |e| (e - 1..e + 1).to_a }.uniq - arr - [-1]
    • @mudasobwa,哦,对不起,第一次没有理解你的想法。你是对的,但我认为我们只能找到可能缺少的元素,比如在编辑后的答案中,没有(e - 1..e + 1).to_a
    • 是的,当然,我只是复制粘贴了我在这里玩过的代码。无论如何,赞成。
    【解决方案2】:

    执行此操作的最有效方法可能是使用inject. 这使您只需一次即可构建一个新数组。它不是特别红,因为您需要编写算法。而不是依赖内置函数。但这可能是最有效的方法。

    以下算法以返回数组的最终值为 n+1 结束每次迭代,其中 n 是最后评估的项目。如果下一个项目将排除该项目,则将其替换为 n+1。如果下一项比上一项大 2 多,它也会插入 n-1。

    present = [0, 1, 2, 4, 5, 6, 9, 10, 12, 13, 17]
    
    present.inject([]) {|absent,n| 
        # If a number has been skipped at n -1 and n +1
        if (absent.empty? or absent.last < n - 1) && n > 0
           absent << n -1 << n + 1
    
        # if n-1 is already present or the new array is still empty, add n+1
        elsif absent.empty? or absent.last == n-1 
          absent << n + 1
    
        # if the last element of the absent list should be excluded because it is n, replace it with n+1
        elsif  absent.last == n
          # replace last absent with next
          absent[absent.length-1] = n + 1 
          absent
    
        # in all other cases do nothing
        else absent
        end
    }
    
    # => [3, 7, 8, 11, 14, 16, 18]
    

    【讨论】:

      【解决方案3】:
      arr = [0, 1, 2, 4, 5, 6, 9, 10, 12, 13, 17]
      
      b = ([arr[0]-1,0].max..arr[-1]+1).to_a - arr
        #=> [3, 7, 8, 11, 14, 15, 16, 18] 
      (b - b.each_cons(3).with_object([]) { |(c,d,e),f| f << d if e==c+2 })
        #=> [3, 7, 8, 11, 14, 16, 18]
      

      【讨论】:

        【解决方案4】:
        array = [0, 1, 2, 4, 5, 6, 9, 10, 12, 13, 17]
        range = (0..(array.max + 1))
        (range.to_a - array).select do |el| 
          [el-1, el+1].any?{|el2| array.include?(el2)}
        end
        # => [3, 7, 8, 11, 14, 16, 18]
        

        【讨论】:

          猜你喜欢
          • 2011-07-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-11
          • 2017-11-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多