给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:
更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
返回 k 。
判题标准:
系统会用下面的代码来测试你的题解:
int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案
int k = removeDuplicates(nums); // 调用
assert k == expectedNums.length;
for (int i = 0; i
题目中要求于要原地删除重复元素,这里有一个知识点:原地
原地的意思是算法的空间复杂度要为O(1)
下面我给出两种解题方法:
【算法思路】要删除重复的元素并且只能原地删除,那么就不能考虑用哈希表以及辅助数组了。我们可以这样做:有一个偏移变量offset,这个offset所到的位置,就存放那个唯一的值。
具体实现:使用一个变量offset,初值设为0,再设一个变量为length,初值为1,然后从nums的第二个元素(偏移为1)开始遍历整个nums数组,遍历过程中,在设置一个变量j,从0开始一直到i-1,在nums中找这些偏移的值是否有值和nums[i]相同,如果有相同的话,直接跳过,如果所有元素都不相同,那么就需要将这个值存到nums数组中offset+1的位置(因为offset位置已经有元素了),以此类推即可完成。
下面是代码实现(我的代码时间复杂度太高,在力扣中遇到大数组就会不能通过,大家看看就好,这种实现是最简单好理解的):
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
offset = 0
length = 1
for i in range(1, len(nums)):
contain_same = False
for j in range(0, i):
if nums[i] == nums[j]:
contain_same = True
if contain_same:
continue
else:
offset += 1
nums[offset] = nums[i]
length += 1
return length
思路:我们直接设置一个长度为2的滑动窗口(即一个窗口包含两个元素),从最开始一直往后滑,如果遇到窗口内元素不相等,那么直接将数据存储起来,存储的时候需要额外的变量来指示偏移的位置,如果元素相等那么直接跳过
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
offset = 1
for i in range(1, len(nums)):
if nums[i] != nums[i - 1]: # nums[i] 不是重复项
nums[offset] = nums[i] # 保留 nums[i]
offset += 1
return offset
'''
注意:本代码参考以下大佬的代码:
------------------------------------------------------------------------
作者:灵茶山艾府
链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array/solutions/2807162/gen-zhao-wo-guo-yi-bian-shi-li-2ni-jiu-m-rvyk/
来源:力扣(LeetCode)
------------------------------------------------------------------------
'''
有时候我们的代码能够运行成功,但是力扣上过不去,是因为时间复杂度过高,可以用时间复杂度较低的算法。另外本题题目要求只能原地删除,否则可以借助辅助数组、哈希表来做题,时间复杂度也是O(n)!
参与评论
手机查看
返回顶部