问题描述
小R有一个特殊的随机播放规则。他首先播放歌单中的第一首歌,播放后将其从歌单中移除。如果歌单中还有歌曲,则会将当前第一首歌移到最后一首。这个过程会一直重复,直到歌单中没有任何歌曲。例如,给定歌单 [5, 3, 2, 1, 4],真实的播放顺序是 [5, 2, 4, 1, 3]。保证歌曲中的id两两不同。
思路:
这道题目意思是播放第一首歌,并移除,然后将更新后的歌单里的第一首歌移到最后一首,重复该过程,一直到歌单为空。像类似这种边遍历边移除的问题,通常可以采用队列的方式解题。队列是先进先出的,创建队列一般使用deque()方法,删除一般删除即将出队的元素,使用popleft()方法,因为一般队列先进的在左。本题使用单端队列,像双端队列的 话还可以删除最右边的元素。 假设初始队列为[5,3,2,1,4] 播放 5,同时移除5,剩余队列:[3,2,1,4],将3移到队尾得[2,1,4,3] 播放 2,同时移除2,剩余队列:[1,4,3],将1移到队尾得[4,3,1]播放 4,同时移除4,剩余队列:[3,1],将3移到队尾得[1,3]播放 1,移除1,剩余队列:[3],将3移到队尾,队列仍为[3] 播放3,队列空,结束。 最终返回5,2,4,1,3
代码思路:
- 初始化一个空的列表(用来保存最终输出结果)
- 初始化队列,将给定的歌曲列表放入队列
- 当队列不为空:
- 播放队列的第一个元素,加入结果列表
- 移除该元素
- 队列不为空,将当前队列的第一个元素移到队尾
- 返回结果列表
python代码实现
from collections import deque
def solution(n: int, a: list) -> list:
# 将歌曲列表转为队列
queue = deque(a)
result = []
while len(queue)>0:
# 播放队列的第一首歌
result.append(queue.popleft()) # popleft() 从队列头部移除并返回
# 如果队列中还有歌曲,将当前第一首歌移到队尾
if len(queue)>0:
queue.append(queue.popleft()) # 将队首的歌移动到队尾
return result
if __name__ == '__main__':
print(solution(n = 5, a = [5, 3, 2, 1, 4]) == [5, 2, 4, 1, 3])
print(solution(n = 4, a = [4, 1, 3, 2]) == [4, 3, 1, 2])
print(solution(n = 6, a = [1, 2, 3, 4, 5, 6]) == [1, 3, 5, 2, 6, 4])
)
题目描述
小S正在帮助她的朋友们建立一个搜索引擎。为了让用户能够更快地找到他们感兴趣的帖子,小S决定使用倒排索引。倒排索引的工作原理是:每个单词都会关联一个帖子ID的列表,这些帖子包含该单词,且ID按从小到大的顺序排列。
例如,单词“夏天”可能出现在帖子1、帖子3和帖子7中,那么这个单词的倒排链就是 [1, 3, 7]。如果用户想同时找到包含“夏天”和“海滩”的帖子,小S需要找出两个倒排链的交集,且将结果按照从大到小的顺序输出。现在,给定两个单词的倒排链数组 a 和 b,请你帮助小S找出同时包含这两个单词的帖子ID,并按从大到小的顺序返回结果。
思路
这道题需要使用每个单词的倒排链是一个帖子ID的有序列表(升序),即每个列表a和b均是按从小到大的顺序排列。 如果用户想查找同时包含两个单词的帖子,我们需要找到a和b的交集。可以将两个列表转换为集合并使用集合的交集运算。集合交集可以快速找到两个列表中共有的元素。
代码实现
def solution(a, b):
# 找到交集
result = sorted(set(a).intersection(b), reverse=True)
return result
if __name__ == '__main__':
print(solution([1, 2, 3, 7], [2, 5, 7]) == [7, 2])
print(solution([1, 4, 8, 10], [2, 4, 8, 10]) == [10, 8, 4])
print(solution([3, 5, 9], [1, 4, 6]) == [])
print(solution([1, 2, 3], [1, 2, 3]) == [3, 2, 1])