剑指 Offer 03. 数组中重复的数字

本文用于学习记录


前言

剑指 Offer 03. 数组中重复的数字 中用到的 python 函数、方法以及哈希表与原地交换算法理解。


一、python 内置函数

1. set() 函数

创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。
实例:

>>> x = set('eleven')
>>> y = set('twelve')
>>> x,y
({'l', 'e', 'n', 'v'}, {'e', 'v', 'l', 't', 'w'})
>>> x & y  #交集
{'l', 'e', 'v'}
>>> x | y  #并集
{'e', 'v', 'n', 'l', 't', 'w'}
>>> x - y  #差集
{'n'}
>>> y -x   #差集
{'t', 'w'}
>>> x ^ y  #补集
{'t', 'n', 'w'}
>>> y ^ x  #补集
{'w', 'n', 't'}
>>> 
交集 & : x&y,返回一个新的集合,包括同时在集合 x 和y中的共同元素。
并集 | : x|y,返回一个新的集合,包括集合 x 和 y 中所有元素。
差集 - : x-y,返回一个新的集合,包括在集合 x 中但不在集合 y 中的元素。
补集 ^ : x^y,返回一个新的集合,包括集合 x 和 y 的非共同元素。

2. range() 函数

2.1 函数用法:

Python3 range() 函数返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以打印的时候不会打印列表;

>>> type(range(10))
<class 'range'>

Python3 list() 函数是对象迭代器,可以把range()返回的可迭代对象转为一个列表,返回的变量类型为列表;

>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Python2 range() 函数返回的是列表;

>>>range(10)        # 从 0 开始到 9
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 11)     # 从 1 开始到 10
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> range(0, 30, 5)  # 步长为 5
[0, 5, 10, 15, 20, 25]
>>> range(0, 10, 3)  # 步长为 3
[0, 3, 6, 9]
>>> range(0, -10, -1) # 负数
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> range(0)
[]
>>> range(1, 0)
[]

python2.x range() 函数可创建一个整数列表,一般用在 for 循环中。

>>>x = 'runoob'
>>> for i in range(len(x)) :
...     print(x[i])
... 
r
u
n
o
o
b
>>>

2.2 函数语法:

range(stop)
range(start, stop[, step])

2.3 参数说明:

start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(05;
stop: 计数到 stop 结束,但不包括 stop。例如:range(05) 是[0, 1, 2, 3, 4]没有5
step:步长,默认为1。例如:range(05) 等价于 range(0, 5, 1)

3. len() 方法

返回对象(字符、列表、元组等)长度或项目个数。
实例如下:

#!/usr/bin/env python
#coding=utf-8
 
str = "runoob"
print( len(str) )          # 字符串长度
 
l = [1,2,3,4,5]
print( len(l) )            # 列表元素个数

#执行以上代码,输出结果为:
#6
#5

二、python 集合方法

1. add() 方法

add() 方法向集合添加元素。
如果该元素已存在,则 add() 方法就不会添加元素。
实例:

thisset = {"apple", "banana", "cherry"}

thisset.add("orange")

print(thisset)

#{'orange', 'banana', 'cherry', 'apple'}

三、剑指 Offer 03. 数组中重复的数字

代码如下:

class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        # 方法一:哈希表 / Set
        # 利用数据结构特点,容易想到使用哈希表(Set)记录数组的各个数字,当查找到重复数字则直接返回。

        # 算法流程:
	        # 初始化: 新建 HashSet ,记为 dic ;
	        # 遍历数组 nums 中的每个数字 num :
	        # 当 num 在 dic 中,说明重复,直接返回 num ;
	        # 将 num 添加至 dic 中;
	        # 返回 −1 。本题中一定有重复数字,因此这里返回多少都可以。
        
        # 复杂度分析:
			# 时间复杂度 O(N):遍历数组使用 O(N),HashSet 添加与查找元素皆为 O(1) 。
			# 空间复杂度 O(N):HashSet 占用 O(N)大小的额外空间。

        dic = set()
        for num in nums:
            if num in dic: return num
            dic.add(num)
        return -1 
		
		# 方法二:原地交换
		# 遍历中,第一次遇到数字 x 时,将其交换至索引 x 处;而当第二次遇到数字 x 时,一定有 nums[x]=x ,此时即可得到一组重复数字。

		# 算法流程:
			# 遍历数组 nums,设索引初始值为 i=0:
			# 若 nums[i]=i: 说明此数字已在对应索引位置,无需交换,因此跳过;
			# 若 nums[nums[i]]=nums[i]: 代表索引 nums[i] 处和索引 i 处的元素值都为 nums[i],即找到一组重复值,返回此值 nums[i];
			# 否则: 交换索引为 i 和 nums[i] 的元素值,将此数字交换至对应索引位置。
			# 若遍历完毕尚未返回,则返回 −1。

		# 复杂度分析:
			# 时间复杂度 O(N) : 遍历数组使用 O(N) ,每轮遍历的判断和交换操作使用 O(1)。
			# 空间复杂度 O(1) : 使用常数复杂度的额外空间。

        # i = 0
        # while i < len(nums):
            # if nums[i] == i:
                # i += 1
                # continue
            # if nums[nums[i]] == nums[i]: return nums[i]
            # nums[nums[i]], nums[i] = nums[i], nums[nums[i]]
        # return -1

原地交换算法


总结

以上就是剑指 Offer 03. 数组中重复的数字中用到的 python 函数、方法以及哈希表与原地交换算法理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

701044

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

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

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

打赏作者

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

抵扣说明:

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

余额充值