剑指 Offer 03. 数组中重复的数字
数组长度为n,但数的范围在0到n-1。所以必定有重复。但直接遍历真的太憨憨了:sweat_smile:(是我没错了)。
- 使用哈希表的set()【集合】方法
set对象的每一个元素要求可进行哈希运算,set 会对内部元素进行去重,每个元素在同一个set 中只会出现一次;
字典可以将一个可哈希值映射到一个任意对象,可以通过映射关系快速查找对应数据;所以在dict中的每一项由一个key-value对组成(也称pairs) ,其中key 会作为字典快速查找的的一个关键数据,所以要求一个字典中键必须是唯一,并可哈希,若在赋值过程中出现相同的key值,后者将会覆盖之前的内容。
归根结底数据结构掌握不全。
class Solution: def findRepeatNumber(self, nums: List[int]) -> int: s = set() for i in range(len(nums)): if nums[i] in s: return nums[i] s.add(nums[i]) return -1
- 原地交换
结合题目,数组长度为n,但数的范围在0到n-1。因此,将索引与数值一一对应就可以找到重复的。
class Solution: def findRepeatNumber(self, nums) -> int: i=0 while i < len(nums): if nums[i] == i: # 两个判断语句的顺序不能换;如果没有第一个判断第二个就会产生错误 i=i+1 continue if nums[nums[i]] == nums[i]: # 找到重复就推出 return nums[i] # 索引与值不对应就一直调换顺序,直到相同在去下一个位置; tmp = nums[i] nums[i] = nums[tmp] nums[tmp] = tmp return -1
剑指 Offer 53 - I. 在排序数组中查找数字 I :star::star
刚开始自己的思路是使用二分查找法找到位置,再看目标数字出现的次数。但写的太麻烦了,还有好多错误。
- 改进二分法转换为寻找目标的左边界和右边界
左边界和右边界的寻找,也正好是我感到困难的地方。因为要顾及到是否超出列表的索引范围
def search(nums, target: int) -> int: # 搜索右边界 right i, j = 0, len(nums) - 1 while i <= j: m = (i + j) // 2 if nums[m] <= target: i = m + 1 # 即使找到目标也将索引右移,最终索引的值刚好比目标值大 else: j = m - 1 right = i # 若数组中无 target ,则提前返回 if j >= 0 and nums[j] != target: return 0 # 搜索左边界 left i = 0 while i <= j: m = (i + j) // 2 if nums[m] < target: i = m + 1 else: j = m - 1 left = j return right - left - 1