1.多数元素
问题:
给定一个大小为 n
的数组 nums
,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋
的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
方法1: 哈希表
实时判断,找到过半元素,直接退出即可
# 方法1:哈希表
# 实时判断,找到过半元素,直接退出即可
def majorityElement(nums):
hash = collections.defaultdict(int)
for num in nums:
hash[num] += 1
if hash[num] > len(nums)//2:
return num
方法2:排序
找中位,如果过半,中位元素就是要找的,只用判断中位元素是否超过数组的一半
# 方法2:排序
# 找中位,如果过半,中位元素就是要找的,只用判断中位元素是否超过数组的一半
def majorityElement(nums):
nums.sort()
# return nums[len(nums)//2] if nums.count(nums[len(nums)//2]) > len(nums)//2 else False # 题目已经保证必然存在多数元素,不用多此一举
return nums[len(nums)//2]
方法3:投票
最多的元素+1,否则-1,如果最多的元素过半,最后票数总为正。
# 方法3:投票
# 最多的元素+1,否则-1,如果最多的元素过半,最后票数总为正
def majorityElement(nums):
vote, max_num = 1, nums[0]
for i in range(1, len(nums)):
if max_num == nums[i]:
vote += 1
else:
vote -= 1
if vote < 0:
max_num, vote = nums[i], 1 # 注意:这里投票也要更新
# return max_num if vote > 0 else False # 题目已经保证必然存在多数元素,不用多此一举
return max_num
2. 只出现一次的数字
问题:
给你一个 非空 整数数组 nums
,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
方法1:异或
# 方法1:异或
def singleNumber(nums):
res = 0
for num in nums:
res ^= num
return res
方法2:哈希表
# 方法2:哈希表
def singleNumber(nums):
hash = collections.defaultdict(int)
for num in nums:
hash[num] += 1
for key, value in hash.items():
if value == 1:
return key
3.颜色分类
方法1:计数 覆盖
# 方法1:计数 覆盖
# 分别统计三个数字的数量,在原数组上进行覆盖
def sortColors(nums):
num0, num1, num2 = 0, 0, 0
# 统计
for num in nums:
if num == 0:
num0 += 1
elif num == 1:
num1 += 1
else:
num2 += 1
# 原地替换
for i in range(len(nums)):
if i < num0:
nums[i] = 0
elif num0 <= i < (num0+num1):
nums[i] = 1
else:
nums[i] = 2
print(nums)
方法2:三指针
# 方法2:三指针
# 相当于把0/1/2分为左/中/右三块,如果为0/2则与左/右元素换位
def sortColors(nums):
left, cur, right = 0, 0, len(nums)-1
while cur <= right:
# 0入左边
if nums[cur] == 0:
nums[left], nums[cur] = nums[cur], nums[left]
left += 1
cur += 1 # 从cur交换到left的元素只可能是1(否则left不会指向它)
# 2入右边
elif nums[cur] == 2:
nums[right], nums[cur] = nums[cur], nums[right]
right -= 1
# 注意:这里cur不能增加,从2换来的元素可能是0/1,必须重新检查
# 中间1不用管
else:
cur += 1
print(nums)