Python 如何改进删除重复的算法?

Python 如何改进删除重复的算法?,python,algorithm,Python,Algorithm,我的采访问题是,我需要返回删除重复项的数组的长度,但最多可以保留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:

我的采访问题是,我需要返回删除重复项的数组的长度,但最多可以保留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

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

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

这是我的逻辑

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]
希望这有帮助。

int-removeDuplicates(vector&nums){
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;
}
if(nums.size()==0)返回nums.size(); int state=1; int-idx=1; 对于(int i=1;i

想法:维护一个记录当前重复时间的变量(状态)(更准确地说,状态记录当前元素左侧相邻元素的重复时间)。此算法为O(n),对数组进行一次扫描。

如果原始数组大小为
n

  • 计算数组中的不同数字

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

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

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

    我会忘记生成新数组,而只关注计数:

    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)
    
    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
    

    使用
    Counter
    dict
    @JonathonReinhart code Review只接受按预期工作的代码-这篇文章底部的问题可能需要改写一下,以避免吸引“不清楚你在问什么”或“坏代码”的投票。O(2n)=O(n),因为你必须读取整个数组,所以你做得再好不过了。如果你正在寻找一个恒定的时间加速,考虑一下。你的代码看起来和我能得到的一样好。你最多可以离开2个副本,这意味着你可以有零副本,对吗?那么为什么不
    列表(set([1,1,1,2,2,3])
    ?也应该是O(n),但simplerI看不到该项返回任何内容,它会打印未请求的内容。此练习的目的是删除列表中出现两次以上的项目。我在回答中给出的例子很好地回答了@toy的问题。直接从python IDE粘贴输出。
    我需要返回数组的长度
    len(newl)
    应该做什么。这个想法是为了提出一个可行的替代方案。他知道如何提取数组的长度。这取决于
    duplicate
    的解释。(如果所有数字都是唯一的,但至少有一个出现了三次,则是
    d+1
    正确,
    d+2
    ,两者都是或没有?)