定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
var nums:[Int] = [1, 1, 2]
var nums:[Int] = [2, 1, 1, 2, 1, 1]
近日刷题遇到了这个题目,一开始的解题方法为
func removeDuplicates(_ nums : inout [Int]) -> Int {
var result : [Int] = []
for i in 0..<nums.count {
if result.contains(nums[i]) == false {
result.append(nums[i])
}
}
print("自己的方法:\(result)")
return nums.count
}
然后开开心心的填上了答案,代码输出结果正确,结果报超时???
然后去看了答案,答案提到了双指针法,看了几遍懂了他的意思,确实比我的方法时间复杂度简单很多。我的是O(n2),他的是O(n),差别太大。
于是去写下了代码
func removeDuplicates3(_ nums: inout [Int]) -> Int {
if (nums.count == 0) { return 0 }
var i = 0
for j in 1..<nums.count {
if (nums[i] != nums[j]) {
i = i + 1
nums[i] = nums[j]
}
}
print("nums\(nums)")
return (i + 1)
}
结果输出
nums[2, 1, 2, 1, 1, 1]
这明显就是没有去掉后边的值啊,不知道为啥网上全是这种。
优化了一下,写出来了自己的的答案
func removeDuplicates2(_ nums: inout [Int]) -> Int {
// 先做错误处理
if nums.count==0 || nums.count==1 {
return nums.count
}
print("排序之前的nums:\(nums)")
nums.sort()
print("排序之后的nums:\(nums)")
var index = 0
var result = [nums[index]]
for i in 1..<nums.count {
print("i = \(i)\nindex = \(index)")
if nums[i] != result[index] {
index += 1
result.append(nums[i])
}
}
nums = result
print("2ssssss : \(nums)")
return index+1
}
这答案是正确了,仔细的审题了一下,发现,首先排序没必要,其次不能借助第二个数组
于是继续优化了一下
func removeDuplicates4(_ nums: inout [Int]) -> Int {
if (nums.count == 0) { return 0 }
var i = 0
for j in 1..<nums.count {
if (nums[i] != nums[j]) {
i = i + 1
nums[i] = nums[j]
}
}
nums.removeLast(nums.count-i+1)
print("nums\(nums)")
return (i + 1)
}
这次结果就正确了
刚开始刷算法题,很多思路都欠缺,比如时间复杂度和空间复杂度的问题。甚至一开始审题的时候没有注意到是删除 排序 数组中的重复项,我又自己拍了个序。
本次题目学到东西有
- 1、审题要仔细,多余的操作就是冗余
- 2、要多去向更好的办法
- 3、本次题目学到的是 双指针法。