LeetCodeEasy-【面试题03. 数组中重复的数字】

论坛 期权论坛 脚本     
匿名技术用户   2021-1-7 00:46   24   0

找出数组中重复的数字。


在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

示例 1:

输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3

限制:

2 <= n <= 100000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:

思路1:数组

思路2:字典

思路3:set集合

思路4:原地置换算法


思路1:数组

只需要找到一个重复的数字即可,可以采用一个数组进行模拟,利用下标与数字对应,数组中的值作为出现次数。

时间和空间复杂度都是 O(n)

class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        length = len(nums)
        count = [0] * length
        for i in range(length):
            count[nums[i]] += 1
            if count[nums[i]] > 1:
                return nums[i]
        return -1

思路2:字典

将上面的数组换成字典即可,依然可以统计次数.

时间复杂度:O(n)

空间复杂度:O(n), 应该比上面的数组要少。

class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        length = len(nums)
        count = {}
        for i in range(length):
            if nums[i] in count:
                return nums[i]
            else:
                count[nums[i]] = 1
        return -1

思路3:set集合

将上面的数组换成set集合即可,判断是否之前是否已经存在与集合即可.

时间复杂度:O(n)

空间复杂度:O(n)

class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        length = len(nums)
        count = set()
        for i in range(length):
            if nums[i] in count:
                return nums[i]
            else:
                count.add(nums[i])
        return -1

思路4:原地置换算法

这个方法非常巧妙,就一个根据题目知道:大小为N的数组中的数值是在[0,n-1]的,那么如果数组不重复,就应该可以一个下表对应一个数字,且是一一对应的即小标 i = num[i]的。所以我们就可以以用这一点进行判断,如果某一个下标对应了两个值那么就存在重复数字。

处理方法上:就是遍历数组,进行调整顺序,将i和nums[i]对应好,如果 i!=nums[i] 不相等,则需要将nums[i]放到下标为nums[i]的位置,并将下标为nums[i]上的值替换到下标为 i 的位置,如果此时 i 还不等于 nums[i] 时,继续上面的操作。

举例如下:

下表:0 1 2 3

值: 1 3 0 2

自己手动按照上面的处理方式演算以下即可领会。

此题的巧妙之处是不需要额外的存储空间,且时间与上面的基本一致,并且提供了一种特定环境下的排序方法

时间复杂度:O(n)

空间复杂度:O(1)

class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        length = len(nums)
        # 原地交换
        for i in range(length):
            while i != nums[i]: # 说明num[i]应该放到下标为num[i]的位置
                if nums[nums[i]] == nums[i]: # 该位置已经匹配好了,则说明存在重复
                    return nums[i]
                t = nums[nums[i]]
                nums[nums[i]] = nums[i]
                nums[i] = t
        return -1

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP