CheckIO是一个通过闯关游戏学习编程的网站(Python和JavaScript)。通过解题开发新“岛屿”,同时,通过做任务获得Quest Points解锁会员题目。
文章内容:题目、我自己的思路和代码以及优秀代码,如果想看大神解题可以直接跳到“优秀代码”部分。
本题链接:https://py.checkio.org/en/mission/reverse-every-ascending/
题目
创建并返回一个新的列表,其元素与原列表相同,但每个严格升序子列表中的元素降序排列。 此函数不应修改原始列表的内容。
输入: 列表
输出: 列表
举个栗子:
reverse_ascending([1, 2, 3, 4, 5]) == [5, 4, 3, 2, 1]
reverse_ascending([5, 7, 10, 4, 2, 7, 8, 1, 3]) == [10, 7, 5, 4, 8, 7, 2, 3, 1]
用处: (math is used everywhere)
假设: 列表中元素均为整数
题目框架
def reverse_ascending(items):
# your code here
return None
if __name__ == '__main__':
print("Example:")
print(reverse_ascending([1, 2, 3, 4, 5]))
# These "asserts" are used for self-checking and not for an auto-testing
assert list(reverse_ascending([1, 2, 3, 4, 5])) == [5, 4, 3, 2, 1]
assert list(reverse_ascending([5, 7, 10, 4, 2, 7, 8, 1, 3])) == [10, 7, 5, 4, 8, 7, 2, 3, 1]
assert list(reverse_ascending([5, 4, 3, 2, 1])) == [5, 4, 3, 2, 1]
assert list(reverse_ascending([])) == []
assert list(reverse_ascending([1])) == [1]
assert list(reverse_ascending([1, 1])) == [1, 1]
assert list(reverse_ascending([1, 1, 2])) == [1, 2, 1]
print("Coding complete? Click 'Check' to earn cool rewards!")
难度: Elementary+
思路及代码
思路
- 定义变量
i
依次找到每个极大值的索引,初始值为0;定义变量temp
为上一次找到的极大值索引+1,初始值为0;定义result
变量存储排序后的结果; - 依次比较前后两个元素大小;
- 找到极大值后,用
sort
函数对items[temp: i+1]
的元素进行排序,并添加到result
列表里; - 由于最后一部分递增元素不能按上面的添加到
result
列表里,所以增加一步第4步的操作,将最后一部分递增元素添加到result
列表
代码
def reverse_ascending(items):
temp = 0
result = []
for i in range(len(items)-1):
if items[i+1] <= items[i]: #相邻元素比较
result += sorted(items[temp:i+1], reverse = True) #逆序排列递增元素
temp = i+1
result += sorted(items[temp:], reverse = True) #最后一部分递增元素
return result
优秀代码
No.1
def reverse_ascending(items):
res=[]
start=0
for i in range(1,len(items)):
if items[i]<=items[i-1]:
res+=items[start:i][::-1]
start=i
return res+items[start:][::-1]
使用切片的方法使元素逆序排列
No.2
另外几个用 yield from
的代码:
def reverse_ascending(iterable):
ascending = []
for elem in iterable:
if ascending and ascending[-1] >= elem:
yield from reversed(ascending)
ascending = []
ascending.append(elem)
yield from reversed(ascending)
def reverse_ascending(items):
run, current = [], -float('inf')
for element in items:
if element > current:
run.append(element)
current = element
else:
yield from run[::-1]
run, current = [element], element
yield from run[::-1] # 或 yield from reversed(run)
def reverse_ascending(items):
indices = [i+1 for i in range(len(items) -1) if items[i] >= items[i+1]]
for i, j in zip([0] + indices, indices + [len(items)]):
yield from items[i:j][::-1]
这个暂时还看不懂。。。