03 数组中的重复数字

03 数组中的重复数字

题目

在这里插入图片描述

解题方法

法一 暴力求解 时间:O(n) 空间:O(1)

算法流程

暴力求解,对数组进行排序,判断相邻元素是否相等,如果相等则输出不相等则继续

复杂度

时间复杂度O(n):内置sort函数O(nlogn), for循环遍历数组O(n)
空间复杂度O(1): 使用常数pre复杂度的额外空间

代码

class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        nums.sort()
        pre =-1
        for i in nums:
            if i==pre:
                return i
            pre=i

法二 哈希表 时间:O(n) 空间:O(n)

算法流程

  1. 初始化: 新建 HashSet ,记为 dic ;
  2. 遍历数组 nums 中的每个数字 num :
    当 num 在 dic 中,说明重复,直接返回 num ;
    将 num 添加至 dic 中;
  3. 返回 −1 。本题中一定有重复数字,因此这里返回多少都可以。

复杂度

时间复杂度O(n):for循环遍历数组O(n),哈希查找添加O(1)
空间复杂度O(n): 使用dict 复杂度O(n)

代码

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

法三 原地哈希 时间:O(n) 空间:O(1)

算法流程

题目中长度为n,则索引为0n-1,而nums中数字的取值范围又在0n-1,因此没有重复的情况下我们就可以让索引和数值一一对应,如果有重复则某一个索引会对应已经出现过的数值,因此找重复数字的算法流程为:

  1. 遍历数组 nums ,设索引初始值为 i=0 :
  2. 判断nums[i]与i是否相等
    若 nums[i]=i : 说明此数字已在对应索引位置,无需交换,继续循环;
    若不相等就去找nums[nums[i]]对应的值
  3. 判断nums[nums[i]]与nums[i]是否相等
    如果nums[nums[i]]=nums[i],那么数组的第i位和第nums[i]位数值相等,返回重复的数字nums[i]
    如果nums[nums[i]]!=nums[i],那么就交换第i位和第nums[i]位的数值,起码让第nums[i]位的值=nums[i]
  4. 若遍历完毕尚未返回,则返回 −1 。

复杂度

时间复杂度O(n):for循环遍历数组O(n),每轮遍历判断和交换O(1)
空间复杂度O(1): 使用常数复杂度的额外空间

代码

class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        n=len(nums)
        for i,num in enumerate(nums):
            while nums[i]!=i:
                m=nums[i]
                #if nums[nums[i]]==nums[i]做判断会陷入死循环,把nums[i]提前保存出来
                if nums[m]==m:
                    return m
                nums[i]=nums[m] 
                nums[m]=m 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时兮ゎ、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值