返回
用Python 精妙破解LeetCode 378:探寻有序矩阵中的第K小元素
闲谈
2023-11-24 12:55:38
欢迎踏入有序矩阵的奥秘世界,我们将一同探索如何在LeetCode 378中寻找第K小元素。沿途,您将领略从暴力解法到二分查找法的算法演进,充分感受算法的魅力和效率之美。
一、暴力解法:直接排序,轻松直达答案
最朴素的解法莫过于将矩阵的所有元素提取出来,组成一个数组,然后对数组进行排序,最后返回第K个元素。这种方法简单粗暴,但计算量过大,时间复杂度为O(n^2logn)。
def find_kth_smallest(matrix, k):
# 将矩阵展开成数组
arr = []
for row in matrix:
arr.extend(row)
# 对数组进行排序
arr.sort()
# 返回第K个元素
return arr[k-1]
二、二分查找:巧妙运用矩阵特性,大幅提升效率
若细究矩阵的特性,您会发现每行和每列都是有序的。因此,我们可以利用二分查找法来缩小搜索范围,大幅提高算法的效率。时间复杂度降至O(nlogn),大大降低计算成本。
原理解析
在有序矩阵中,每一行和每一列都是递增的。这意味着,如果我们能确定某个值的位置,就可以通过它来确定其他位置的值。例如,如果我们找到一个中间值mid
,那么我们可以统计出有多少个元素小于等于这个mid
。根据这个数量与k
的关系,我们可以调整搜索范围,从而逐步逼近第K小的元素。
代码实现
import bisect
def find_kth_smallest(matrix, k):
# 二分查找的目标值
target = k
# 确定矩阵的行数和列数
rows, cols = len(matrix), len(matrix[0])
# 二分查找的左右边界
left, right = matrix[0][0], matrix[rows-1][cols-1]
# 在左右边界之间进行二分查找
while left <= right:
# 计算中间值
mid = (left + right) // 2
# 统计小于等于中间值的元素个数
count = 0
for row in matrix:
index = bisect.bisect_left(row, mid)
count += index
# 如果小于等于中间值的元素个数小于K,则将左边界更新为中间值加1
if count < target:
left = mid + 1
# 如果小于等于中间值的元素个数大于等于K,则将右边界更新为中间值减1
else:
right = mid - 1
# 返回第K小的元素
return left
三、结语:探索算法奥秘,领略编程艺术
LeetCode 378 中寻找有序矩阵的第K小元素之旅已圆满结束。我们从暴力解法开始,逐步升级至二分查找法,见证了算法从低效到高效的演变。在这个过程中,您不仅领略了算法的精妙之处,更对Python编程语言有了更深刻的认识。
未来,在探索算法与编程世界的道路上,愿您继续勇往直前,不断创造属于自己的编程传奇!