根据第 K 场考试的分数排序
题目描述:
班里有 m 位学生,共计划组织 n 场考试。给你一个下标从 0 开始、大小为 m x n 的整数矩阵
score
,其中每一行对应一位学生,而score[i][j]
表示第 i 位学生在第 j 场考试取得的分数。矩阵score
包含的整数 互不相同。
另给你一个整数k
。请你按第 k 场考试分数从高到低完成对这些学生(矩阵中的行)的排序。
返回排序后的矩阵。
示例:
1
2
3
4
5
6
输入:score = [[10,6,9,1],[7,5,11,2],[4,8,3,15]], k = 2
输出:[[7,5,11,2],[10,6,9,1],[4,8,3,15]]
解释:
- 下标为 1 的学生在第 2 场考试取得的分数为 11 ,这是考试的最高分,所以 TA 排在第一。
- 下标为 0 的学生在第 2 场考试取得的分数为 9 ,排第二。
- 下标为 2 的学生在第 2 场考试取得的分数为 3 ,排第三。
解题心路
- 起初尝试用
for
循环找列最大值,再交换行,但语法不熟导致实现复杂。 - 后来发现
score.shape[0]
和score[:, k]
是 NumPy 写法,而题目输入是 Python 原生List[List[int]]
。 - 行交换写法
score[[0,max_index],:] = score[[max_index,0],:]
也是 NumPy 的方式,不能直接用于列表。
知识点整理
- 原生
list[i][j]
不能使用.shape
或数组切片。 np.array([[1, 2], [3, 4]])
则可以使用.shape
和切片如array[:, 1]
。- 排序方法:
1
sorted(score, key=lambda x: x[k], reverse=True)
sorted(...)
是 Python 内置排序函数,返回新列表。key=lambda x: x[k]
表示按每位学生第 k 场考试成绩排序。reverse=True
表示按降序排序。
多级排序:
如果要先按第 k
场成绩,再按第 j
场成绩排序,可写为:
1
sorted(score, key=lambda x: (x[k], x[j]), reverse=True)
按身高排序
巩固知识再看一个类似题目:
给你一个字符串数组
names
,和一个由 互不相同 的正整数组成的数组heights
。两个数组长度均为n
。
每个下标i
,names[i]
和heights[i]
表示第 i 个人的名字和身高。
请按身高 降序 返回对应的名字数组。
示例:
1
2
3
4
5
输入:names = ["Mary","John","Emma"], heights = [180,165,170]
输出:["Mary","Emma","John"]
输入:names = ["Alice","Bob","Bob"], heights = [155,185,150]
输出:["Bob","Alice","Bob"]
解题思路
- 一开始尝试用
dict(zip(...))
构造字典后排序,但发现 key 重复会导致值被覆盖。 - 更好的做法是直接将
(name, height)
对组成列表,再排序:
1
2
3
pairs = zip(names, heights)
sorted_pairs = sorted(pairs, key=lambda x: x[1], reverse=True)
return [name for name, _ in sorted_pairs]
列表推导式知识点回顾
[name for name, _ in sorted_pairs]
是一种列表推导式(List Comprehension),语法如下:
1
[表达式 for 元素 in 可迭代对象]
- 它是一个简洁写法,相当于下面这个循环:
1 2 3 4
result = [] for item in sorted_pairs: name, _ = item result.append(name)
示例:
1
2
3
pairs = [('a', 1), ('b', 2), ('c', 3)]
[x for x, y in pairs] # ['a', 'b', 'c']
[y for x, y in pairs] # [1, 2, 3]