如何使我的ruby remove_duplicates(nums)算法更有效率

时间:2017-12-14 03:13:52

标签: arrays ruby algorithm

这是编码挑战:给定排序数组,就地删除重复项,使每个元素只出现一次并返回新长度。

不要为另一个数组分配额外的空间,必须通过使用O(1)额外内存修改输入数组来实现此目的。

我的回答

def remove_duplicates(nums)

    hash = {}

    nums.each do |num|
      if hash[num].nil?
        hash[num] = 1
      end 
      if hash[num] = 1
        i = nums.index(num)
        nums.delete(num)
        nums.insert(i, num)
      end 
    end

    nums.length    
end

在leetcode上,我的答案通过了160/161个测试用例。但我收到超过时间限制"错误。错误说我的答案不够有效,无法解决最后一个测试用例。

我是初学者,我正在寻找有关如何提高答案效率的建议(红宝石)!

1 个答案:

答案 0 :(得分:2)

如果您不想使用注释中建议的其中一种内置方法,那么在O(n)Time和O(1)Space中执行此操作的一种算法是使用2个索引来循环遍历阵列。第一个将是您上次插入唯一值的索引,第二个是您当前正在查看的元素的索引。关键是nums数组已排序,因此如果它大于当前值,则只需设置下一个值。它不能少(因为排序),如果它等于你插入的最后一个值,它不是唯一的。例如:

nums = [1, 1, 1, 2, 2, 3, 4, 5, 5, 5, 5, 5, 6, 7, 8, 8, 9, 10, 10]
def remove_duplicates(nums)
  return 0 if !nums || nums.empty?
  insertion_index = 0

  1.upto(nums.length - 1) do |lookup_index|
    if nums[lookup_index] > nums[insertion_index]
      insertion_index += 1

      nums[insertion_index] = nums[lookup_index]
    end
  end

  # nums is currently:
  # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 5, 5, 6, 7, 8, 8, 9, 10, 10]
  insertion_index + 1
end

remove_duplicates(nums)

您的返回值将是insertion_index + 1,因为insertion_index是插入最后一个唯一值的索引,因此数组的长度是最终索引+ 1。 / p>

我已经有一段时间了,因为我已经完成了一个leetcode问题,但我似乎记得在这些问题中你需要调整一个阵列的位置,只需将所有内容留在最后就可以了。在Ruby中,但是在其他语言中提交的内容很多,只是简单地调整数组大小并不容易。如果您愿意,可以随意删除最终值(根据说明)(但是如果您需要的是唯一数组的长度),则不需要。