【Leetcode】03.数组中重复的数字&53.在排序数组中查找数字I

剑指offer03. 数组中重复的数字

(列表表示数组,涉及用哈希表计数)

方法一:使用哈希表(dict/set)计数

  • 看到别人的题解大多用的是set,但感觉set的索引效率并不是最高的,至少我自己提交后的结果里dict的内存使用和时间都更优
class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        counts = {}
        for num in nums:
            if num in counts.keys():
                return num
            else:
                counts[num] = None # 只是转成一种遍历效率更高的数据结构
  • 复杂度分析
    • 时间复杂度: O ( n ) O(n) O(n)。遍历数组一遍。使用哈希集合(HashSet),添加元素的时间复杂度为 O ( 1 ) O(1) O(1),故总的时间复杂度是 O ( n ) O(n) O(n)
    • 空间复杂度: O ( n ) O(n) O(n)。不重复的每个元素都可能存入集合,因此占用 O ( n ) O(n) O(n)额外空间。

方法二:原地交换

  • 题目说明中包含在一个长度为 n 的数组 nums 里的所有数字都在 0 ~ n-1 的范围内这一信息。 此说明含义:数组元素的索引和值是一对多的关系。
  • 遍历中,第一次遇到数字 xx 时,将其交换至索引 xx 处;而当第二次遇到数字 xx 时,一定有 nums[x] = xnums[x]=x ,此时即可得到一组重复数字。
class Solution:
    def findRepeatNumber(self, nums: [int]) -> int:
        i = 0
        while i < len(nums):
            if nums[i] == i: # 确认index上的值是index就跳过
                i += 1
                continue
            if nums[nums[i]] == nums[i]:
              return nums[i]# 如果index上已经有一个等于index的值,意味着重复值出现了
            nums[nums[i]], nums[i] = nums[i], nums[nums[i]] # 交换位置,换到index上去
        return -1
  • 复杂度分析
    • 时间复杂度 O ( N ) O(N) O(N): 遍历数组使用 O ( N ) O(N) O(N),每轮遍历的判断和交换操作使用 O ( 1 ) O(1) O(1)
    • 空间复杂度 O ( 1 ) O(1) O(1): 使用常数复杂度的额外空间。

剑指offer53. 在排序数组中查找数字I

方法一:遍历列表进行比较

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        count = 0
        for num in nums:
            if num == target:
                count += 1
        return count

忽视了列表是排序的这一可利用的条件

方法二:二分法

(解决排序数组中的搜索问题用二分法)

排序数组中的所有数字target形成一个窗口,它的左右边界分别为left和right(窗口外的第一个元素),则target的数量为right-left-1。

应用两次二分法分别查找左右边界。为了简化,将二分法封装成函数,转而寻找target和target的右边界

class Solution:
    def search(self, nums: [int], target: int) -> int:
        def helper(tar):
            i, j = 0, len(nums) - 1
            while i <= j:
                m = (i + j) // 2
                if nums[m] <= tar: i = m + 1
                else: j = m - 1
            return i
        return helper(target) - helper(target - 1)
  • 复杂度分析:
    • 时间复杂度 O ( l o g N ) O(log N) O(logN): 二分法为对数级别复杂度。
    • 空间复杂度 O ( 1 ) O(1) O(1) : 几个变量使用常数大小的额外空间。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值