题解 | #成绩排序#
成绩排序
https://www.nowcoder.com/practice/8e400fd9905747e4acc2aeed7240978b
# 为了满足时间复杂度,选用稳定的归并排序,要返回排序后的原下标
# 其实排序时不需要稳定,只要输出时稳定就行,这有两个30分,你告诉我哪个是谁的,我说是谁的就是谁的!
def MergeSort(lst, mode=1):
"""
lst: 待排序的列表
mode: 排序模式, mode=0为降序, mode=1为升序
"""
def merge(arr, ids, left, mid, right):
nonlocal mode
# 待合并的两段的指针
i = left
j = mid+1
tmp = []
itmp = []
while i <= mid and j <= right: # 这个while保证先从两个已排好的段中去除小的部分
if mode == 1:
if arr[i] <= arr[j]: # 这里的=保证了稳定性
tmp.append(arr[i])
itmp.append(ids[i])
i += 1
else:
tmp.append(arr[j])
itmp.append(ids[j])
j += 1
else:
if arr[i] >= arr[j]: # 这里的=保证了稳定性
tmp.append(arr[i])
itmp.append(ids[i])
i += 1
else:
tmp.append(arr[j])
itmp.append(ids[j])
j += 1
while i <= mid: # 以下两个while不用验证mode是因为段内已经排好顺序
tmp.append(arr[i])
itmp.append(ids[i])
i += 1
while j <= right:
tmp.append(arr[j])
itmp.append(ids[j])
j += 1
for i in range(left, right+1):
arr[i] = tmp[i - left]
ids[i] = itmp[i - left]
def mSort(arr, ids, left, right):
if left >= right:
return
mid = (left+right)// 2
mSort(arr, ids, left, mid)
mSort(arr, ids, mid+1, right)
merge(arr, ids, left, mid, right)
n = len(lst)
ids = list(range(n)) # 原下标顺序列表
if n <= 1:
return lst
mSort(lst, ids, 0, n-1)
return lst, ids
while True:
try:
num = int(input().strip())
mode = int(input().strip())
na_list = list()
sc_list = list()
for _ in range(num):
name, score = input().strip().split(' ')
score = int(score)
na_list.append(name)
sc_list.append(score)
sc_list, ids = MergeSort(sc_list, mode)
for i, index in enumerate(ids):
print(' '.join([na_list[index], str(sc_list[i])]))
except:
break
机试可不要这么写,太浪费时间了!!!
最后的空间复杂度没有满足要求,是O(2n)。应该还能优化,不过看了大佬题解我放弃这个思路了。同好们自己有时间去优化吧!
查看10道真题和解析
OPPO公司福利 1155人发布