1、 数组中重复的数字
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
### 一、暴力枚举
### 不考虑时间复杂度和空间复杂度,只求解
### 时间复杂度O(n),空间复杂度O(n)
class Solution(object):
def findRepeatNumber(self, nums):
list1=[]
length=len(nums)
for i in range(length):
if nums[i] not in list1:
list1.append(nums[i])
else:
return nums[i]
###二、时间复杂度优先
###哈希表
### 时间复杂度O(n),遍历,查找;空间复杂度O(n),哈希表占用;
class Solution(object):
def findRepeatNumber(self, nums):
dict={}
length=len(nums)
for i in range(length):
if not dict.get(nums[i]):
dict[nums[i]]=1
else:
dict[nums[i]]=2
return nums[i]
###哈希表
### 时间复杂度O(n),空间复杂度O(n)
class Solution:
def findRepeatNumber(self, nums: [int]) -> int:
dic = set() #哈希表(Set)记录数组的各个数字
for num in nums:
if num in dic: return num #如果该元素在哈希表内,说明重复
dic.add(num) #不在,添加
return -1 #若没有重复元素返回的值
###空间复杂度优先
# 指针+原地排序数组
### 时间复杂度O(nlogn),空间复杂度O(1)
class Solution(object):
def findRepeatNumber(self, nums):
nums.sort()
length=len(nums)
for i in range(1,length):
if nums[i]==nums[i-1]:
return nums[i]
else:
print("没有重复的数组")
### 原地交换
### 空间复杂度O(1),原地修改原数组;
### 时间复杂度O(n),遍历,判断和交换;
### 这里nums[i]与i是一一对应的,如果i对应多个nums[i]那么说明重复
class Solution(object):
def findRepeatNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
length=len(nums)
for i in range(length):
while i!=nums[i]: ###需要使得nums[i]=i 如果已经
if nums[nums[i]]==nums[i]:
return nums[i]
else:
nums[i],nums[nums[i]]=nums[nums[i]],nums[i]
2、 排序数组查找数字的次数
统计一个数字在排序数组中出现的次数。
排序的考点是二分法
- 时间复杂度 O(log N) : 二分法为对数级别复杂度。
- 空间复杂度 O(1) : 几个变量使用常数大小的额外空间。
###二分法
###nums是排序后的数组
###时间复杂度O(logn),空间复杂度O(1)
class Solution:
def search(self, nums , target ) :
left,right=0,len(nums-1)
i,j=0,len(nums)-1
while i<=j:
m=(i+j)//2
if nums[m] > target:
j=m-1
elif nums[m] <target:
i=m+1
elif nums[m] == target:
i=m+1
right=i #i即为target的右索引,指向的是>target的第一个数
if j>=0 and nums[j] != target:
return -1
i,j=0,len(nums)-1
while i<=j:
m=(i+j)//2
if nums[m] > target:
j=m-1
elif nums[m] <target:
i=m+1
elif nums[m] == target:
j=m-1
left = j #j即为target的左索引,指向的是<target的第一个数
return right - left - 1 #对于target的这个区域的右索引是right,左索引是left
###定义zb函数去指向索引优化代码
class Solution:
def search(self, nums , target ) :
def zb(target): #i即为target的右索引,指向的是>target的第一个数
i,j=0,len(nums)-1
while i<=j:
m=(i+j)//2
if nums[m] > target:
j=m-1
elif nums[m] <target:
i=m+1
elif nums[m] == target:
i=m+1
return i
return zb(target) - zb(target-1) #zb(target)返回>target的第一个数,zb(target-1)返回=target的第一个数
##暴力解法
##统计一个数字在任意数组中出现的次数
### 计数器count
###时间复杂度O(n),遍历,判断;空间复杂度O(1)
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
count=0
for each in nums:
if each==target:
count =count + 1
return count
###建立字典计数每个数字重复出现的次数
###时间复杂度O(n),遍历,判断;空间复杂度O(n)
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
dict={}
for each in nums:
if each in dict:
dict[each]=dict[each]+1
else:
dict[each]=1
a=dict.get(target)
return a if a else 0
3、 0-n-1中缺失的数字
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
示例 1:
输入: [0,1,3]
输出: 2
示例 2:
输入: [0,1,2,3,4,5,6,7,9]
输出: 8
###二分法
###时间复杂度O(logn),空间复杂度O(1)
class Solution(object):
def missingNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
length=len(nums)###排序数组用二分法
i,j=0,length-1
while i <= j:
m= (i+j)//2
if nums[m] == m:
i = m+1
else:
j=m-1
return i
###暴力解法
###时间复杂度O(n),空间复杂度O(n)
class Solution(object):
def missingNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
length=len(nums)
list1=list(range(length+1)) #范围
for i in range(length):
list1.remove(nums[i])
for each in list1:
return each
###哈希表
###时间复杂度O(n),3次遍历;空间复杂度O(n)
class Solution(object):
def missingNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dict={}
length=len(nums)
for i in range(length+1):
dict[i]=1 #创建一个字典
for each in nums:
dict[each]=0 #出现的列表的数字对应字典变为0
for i in range(len(dict)) :
if dict[i] == 1: #找到那个value是1对应的key
return i