【问题标题】:How do I improve remove duplicate algorithm?如何改进删除重复算法?
【发布时间】:2015-07-17 04:14:28
【问题描述】:

我的面试问题是我需要返回删除重复的数组的长度,但我们最多可以留下 2 个重复。

例如,[1, 1, 1, 2, 2, 3] 新数组将是 [1, 1, 2, 2, 3]。所以新的长度是 5。我想出了一个 O(2n) 的算法,我相信。我怎样才能提高它是最快的。

def removeDuplicates(nums):
    if nums is None:
        return 0

    if len(nums) == 0:
        return 0

    if len(nums) == 1:
        return 1

    new_array = {}
    for num in nums:
        new_array[num] = new_array.get(num, 0) + 1

    new_length = 0
    for key in new_array:
        if new_array[key] > 2:
            new_length = new_length + 2
        else:
            new_length = new_length + new_array[key]

    return new_length

new_length = removeDuplicates([1, 1, 1, 2, 2, 3])
assert new_length == 5

我的第一个问题是我的算法是否正确?

【问题讨论】:

  • 使用Counterdict
  • @JonathonReinhart 代码审查只接受按预期工作的代码 - 这篇文章底部的问题可能需要重新措辞以避免吸引“不清楚你're ask' 或 "broken code" close votes。
  • O(2n) = O(n),你不能做得比这更好,因为你必须读取整个数组。如果您正在寻找恒定时间加速,请考虑profiling
  • 你的代码看起来和我能得到的一样好。
  • 您可以“最多保留 2 个重复项”,这意味着您可以有零个重复项,对吗?那么为什么不list(set([1,1,1,2,2,3]))?也应该是 O(n) 但更简单

标签: python algorithm


【解决方案1】:

您的逻辑是正确的,但是他是实现您在问题中提到的目标的更简单方法。

这是我的逻辑。

myl = [1, 1, 1, 2, 2, 3, 1, 1, 1, 2, 2, 3, 1, 1, 1, 2, 2, 3]

newl = []

for i in myl:
    if newl.count(i) != 2:
        newl.append(i)

print newl
[1, 1, 2, 2, 3, 3]

希望这会有所帮助。

【讨论】:

  • 我看不到这会返回任何东西,而且它会打印一些不需要的东西。
  • 练习的目的是删除任何出现的项目,如果该项目在列表中出现两次以上。我在回答中给出的示例可以很好地回答@toy 的问题。输出直接从 python IDE 粘贴。
  • I need to return the length of an array
  • len(newl) 应该可以。这个想法是提出一个可行的替代解决方案。他知道如何提取数组的长度。
【解决方案2】:

如果你的原始数组大小是n

  1. 计算数组中的不同数字。

  2. 如果您有 d 不同的数字,那么您的答案将是

     d        (when n == d)
     d+1      (when n == d+1)
     d+2      (when n >= d+2)
    

如果您的数组中的所有数字都小于n-1,您甚至可以在不使用任何额外空间的情况下解决这个问题。如果是这种情况,请检查 this,您可以非常轻松地计算不同的数字,而无需使用额外的空间。

【讨论】:

  • 取决于duplicate的解释。 (如果所有数字都是唯一的,但一个至少出现三次,d+1 正确,d+2,两者都有还是没有?)
【解决方案3】:

我会忘记生成新数组,只专注于计数:

from collections import Counter

def count_non_2dups(nums):
    new_len = 0
    for num, count in Counter(nums).items():
        new_len += min(2, count)
    return new_len

【讨论】:

    【解决方案4】:
    int removeDuplicates(vector<int>& nums) {
        if (nums.size() == 0) return nums.size();
        int state = 1;
        int idx = 1;
        for (int i = 1; i < nums.size(); ++i) {
            if (nums[i] != nums[i-1]) {
                state = 1;
                nums[idx++] = nums[i];
            }
            else if (state == 1) {
                state++;
                nums[idx++] = nums[i];
            }
            else {
                state++;
            }
        }
        return idx;
    }
    

    idea:维护一个变量(state)记录当前的重复次数(更准确地说,state记录的是当前元素左边相邻元素的重复次数)。该算法是 O(n) 一次扫描数组。

    【讨论】:

      【解决方案5】:
      def removeDuplicates(nums):
          if nums is None:
              return 0
      
          if len(nums) == 0:
              return 0
      
          if len(nums) == 1:
              return 1
      
          new_array_a = set()
          new_array_b = set()
          while nums:
              i = nums.pop()
              if i not in new_array_a:
                  new_array_a.add(i)
              elif i not in new_array_b:
                  new_array_b.add(i)
      
          return len(new_array_a) + len(new_array_b)
      

      【讨论】:

        猜你喜欢
        • 2010-11-04
        • 1970-01-01
        • 2014-11-23
        • 1970-01-01
        • 2018-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-13
        相关资源
        最近更新 更多