1. 问题描述
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 o(1) 额外空间的条件下完成。
示例 1:
输入:nums = [1,1,1,2,2,3] 输出:5, nums = [1,1,2,2,3] 解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3。 不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,1,2,3,3] 输出:7, nums = [0,0,1,1,2,3,3] 解释:函数应返回新长度 length = 7, 并且原数组的前七个元素被修改为 0, 0, 1, 1, 2, 3, 3。不需要考虑数组中超出新长度后面的元素。
2. 问题分析
使用滑动窗口+删除元素的方法。
对于nums = [1,1,1,2,2,3]
(1)窗口[1,1,1], 长度=3>2,删除第3个1---->[1,1,2,2,3]
(2)窗口[2,2],长度=2<=2,保留
(3)窗口[3],长度=1<=2,保留
结果:[1,1,2,2,3], 长度=5、
3. 算法思路
思路:
(1)定义窗口: beginindex和endindex标记相同元素的起始和结束位置
(2)遍历数组:用endindex向右扩展,找到相同元素的连续区间
(3)处理重复:当遇到不同元素时,检查当前连续区间的长度
如果长度>2,删除多余的元素
如果长度<=2,直接移动指针
4. 代码实现
from typing import list
class solution:
def remove(self, nums: list[int]) -> int:
if len(nums) <= 2:
return len(nums)
slow = 2 # 从第三个位置开始检查
for fast in range(2, len(nums)):
# 如果当前元素不等于slow指针前两个位置的元素
# 说明可以保留当前元素
if nums[fast] != nums[slow - 2]:
nums[slow] = nums[fast]
slow += 1
return slow
def removeduplicates(self, nums: list[int]) -> int:
if not nums:
return 0
beginindex = 0
endindex = 0
value = nums[beginindex]
while endindex < len(nums):
if nums[endindex] == value:
endindex += 1
else:
if endindex - beginindex > 2:
for i in range(endindex-1, beginindex+1, -1):
nums.pop(i)
beginindex = beginindex + 2
endindex = beginindex
value = nums[beginindex]
else:
beginindex = endindex
value = nums[beginindex]
if endindex - beginindex > 2:
for i in range(endindex-1, beginindex+1, -1):
nums.pop(i)
return len(nums)
if __name__ == '__main__':
#print(solution().removeduplicates([1,1,1]))
#print(solution().removeduplicates([1,1,1,2,2,3]))
print(solution().removeduplicates([0,0,1,1,1,1,2,3,3]))这个算法的代码思路直观,容易理解,使用滑动窗口的概念,但是时间复杂度高,pop(i)操作是o(n),最坏情况时间复杂度是o(n^2),并且需要处理多个边界情况,频繁删除操作导致数组元素频繁移动。可以尝试使用双指针法,时间复杂度降为o(n).
总结
到此这篇关于python每日一练之删除有序数组中的重复项的文章就介绍到这了,更多相关python删除有序数组中的重复项内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论