给你一个整数数组 nums
和一个整数 k
,请返回其中出现频率前 k
高的元素。
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
time_dict = defaultdict(int)
for num in nums:
time_dict[num]+=1
index_dict = defaultdict(list)
for key in time_dict:
index_dict[time_dict[key]].append(key)
key = sorted(list(index_dict.keys()))
result = []
cnt = 0
while key and cnt < k:
result.extend(index_dict[key[-1]])
cnt += len(index_dict[key[-1]])
key.pop()
return result[0: k]
假设输入为nums = [1, 1, 1, 2, 2, 3] k = 2
-
初始化两个字典:
time_dict
用于存储每个数字及其出现的次数。index_dict
用于存储每个出现次数及其对应的数字列表。
time_dict = defaultdict(int) value是一个整数 | |
index_dict = defaultdict(list) value是一个列表 |
2、统计每个数字的出现次数:
遍历 nums
列表,对于每个数字 num
,增加 time_dict[num]
的计数。
执行后,time_dict
为:{1: 3, 2: 2, 3: 1}
3、将数字按出现次数放入 index_dict
:
遍历 time_dict
的键(即数字),并将每个数字添加到 index_dict
中对应的出现次数列表中。
因为index_dict是一个list型的字典,所以要用index_dict[time_dict[key]].append(key)
执行后,index_dict
为:{1: [3], 2: [2], 3: [1]}
(这里的列表元素顺序可能与实际输出不同,因为字典的键是无序的)
4、对出现次数进行排序:
将 index_dict
的键(即出现次数)转换为一个列表,并对其进行排序。
排序后的 key
为:[1, 2, 3]
5、获取前k项:
从排序后的 key
列表的末尾开始,逐个取出出现次数对应的数字列表,并添加到 result
中,直到 result
中的元素数量达到 k
个或 key
列表为空。
在这个例子中,因为 k
是2,所以我们首先取出出现次数为3的数字列表(即[1]),然后取出出现次数为2的数字列表(即[2])。此时,result
为 [1, 2]
,并且 cnt
(即 result
中的元素数量)为2,达到了 k
的值,所以循环结束。
暴力解法(但leetcode没通过/(ㄒoㄒ)/~~)
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
left = 0
right = k
maxw = 0
result = []
while right<=len(nums):
maxw = max(nums[left:right])
result.append(maxw)
left +=1
right+=1
return result
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
ans = []
q = deque() # 双端队列
for i, x in enumerate(nums):
# 1. 入
while q and nums[q[-1]] <= x:
q.pop() # 维护 q 的单调性
q.append(i) # 入队
# 2. 出
if i - q[0] >= k: # 队首已经离开窗口了
q.popleft()
# 3. 记录答案
if i >= k - 1:
# 由于队首到队尾单调递减,所以窗口最大值就是队首
ans.append(nums[q[0]])
return ans