删除排序数组中的重复项

116 阅读2分钟

定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 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、本次题目学到的是 双指针法