Python 基础算法——删除有序数组中的重复项 II

13. 删除有序数组中的重复项 II

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

示例:

输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 [1, 1, 2, 2, 3] ,不需要考虑数组中超出新长度后面的元素。

 常用的算法是:双指针法 快慢指针法函数法 

 

双指针法:(此方法思路是对的,但是它创造了额外的空间)

双指针法的思路:使用两个指针来遍历数组,同时用一个计数器来记录当前元素出现的次数,如果超过两次就跳过,否则就覆盖到前面的位置。这样可以保证前面的元素都是符合条件的,而后面的元素都是多余的。

# 双指针法    时间复杂度:O(n)    空间复杂度:O(1)
def remove_dupulicates1(nums):
    # 如果数组为空或之只有一个元素,直接返回数组长度
    if len(nums) <= 1:
        return len(nums)
    # 初始化两个指针 和 一个计数器,i 指向第一个元素, j 指向第二个元素
    i, j, count = 0, 1, 1
    # 遍历数组,直到 j 到达末尾
    while j < len(nums):
        # 如果 j 指向的元素 和 i 指向的元素相同,说明有重复, 更新计数器
        if nums[j] == nums[i]:
            count += 1
            # 如果计数器小于2, 说明当前元素还可以出现一次,就将它放到 i 的下一个位置,并更新 i 和 j
            if count <= 2:
                nums[i + 1] = nums[j]
                j += 1
                i += 1
            # 否则计数器大于2,说明当前元素不可以出现了,更新 j 的位置
            else:
                j += 1
        # 否则,重置计数器 count 
        else:
            count = 1

    return i + 1

快慢指针法:(此方法是从双指针法优化而来的)

快慢指针法的思路:使用两个指针来遍历数组,快指针用来检查每个元素是否符合条件,慢指针用来覆盖要保留的元素。如果快指针指向的元素和慢指针及其前一个元素相同,说明这个元素已经出现了两次,需要跳过,否则就覆盖到慢指针的下一个位置。这样可以保证前面的元素都是符合条件的,而后面的元素都是多余的。

# 快慢指针    时间复杂度:O(n)    空间复杂度:O(1)
def remove_dupulicates2(nums):
    # 元素可以重复2次,慢针可以从第二个元素开始,快针可以从第三元素开始
    slow = 1
    # 遍历数组,直到fast到达末尾
    for fast in range(2, len(nums)):
        # 判断快针元素是否与慢针和慢针前一个元素是否相等
        if nums[fast] == nums[slow] and nums[fast] == nums[slow-1]:
            continue
        slow += 1
        nums[slow] = nums[fast]
                
    return slow + 1

 

 函数法:(此方法思路是对的,但是它创造了额外的空间,但在力扣却能运行,我也不懂为什么能正确运行)

函数法的思路:使用Counter类来统计每个元素出现的次数,然后将超过两次的元素减少到两次,最后将Counter对象转换为列表,并覆盖原数组。这个方法的优点是简洁易懂,缺点是需要额外的空间来存储Counter对象。

# 函数法    时间复杂度:O(n)    空间复杂度:O(n)
def remove_dupulicates3(nums):
    dict = Counter(nums)
    for i in dict:
        if dict[i] > 2:
            dict[i] = 2
    
    list1 = list(dict.elements())
    nums.clear()
    nums.extend(list1)
    return len(nums)

 

题目来源:力扣

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值