矩阵幸运数查找算法与Python实现 1. 题目解析与核心思路1380题要求我们找出矩阵中的幸运数。根据题目定义幸运数需要同时满足两个条件在所在行是最小值在所在列是最大值这个定义看似简单但实际处理时需要特别注意边界条件和效率问题。我们先来看一个具体例子给定矩阵 [ [3,7,8], [9,11,13], [15,16,17] ]在这个3x3矩阵中第一行最小值是3第一列检查第一列的最大值比较3,9,15 → 153不是该列最大值所以不是幸运数最终发现15满足条件它所在行最小所在列最大1.1 暴力解法分析最直观的解法是双重循环遍历每一行找到该行最小值及其列索引检查该值是否也是其所在列的最大值记录所有满足条件的数这种方法时间复杂度为O(m*n)因为最坏情况下需要检查每个元素。对于m行n列的矩阵我们需要m次行遍历找最小值最多m次列检查虽然这不是最优解但对于LeetCode的测试用例规模已经完全够用。下面我们来看具体实现。2. Python实现与优化2.1 基础实现版本def luckyNumbers(matrix): lucky [] for row in matrix: min_val min(row) col_idx row.index(min_val) column [matrix[i][col_idx] for i in range(len(matrix))] if min_val max(column): lucky.append(min_val) return lucky这个实现有几个关键点使用内置min()找出行最小值index()方法获取列索引列表推导式生成列数据比较是否为列最大值注意在Python中min()和max()的时间复杂度都是O(n)所以整体复杂度确实是O(m*n)2.2 优化方向虽然上述解法已经足够但我们还可以做一些优化预处理列最大值 可以先遍历一次矩阵记录每列的最大值这样后续检查时可以直接比较避免重复计算。def luckyNumbers(matrix): if not matrix: return [] # 预处理列最大值 col_max [max(col) for col in zip(*matrix)] lucky [] for row in matrix: min_val min(row) col_idx row.index(min_val) if min_val col_max[col_idx]: lucky.append(min_val) return lucky使用numpy库面试时不建议 如果允许使用第三方库numpy可以简化操作import numpy as np def luckyNumbers(matrix): arr np.array(matrix) return [x for x in arr.min(axis1) if x in arr.max(axis0)]不过要注意面试时通常要求不依赖第三方库。3. 复杂度分析与边界情况3.1 时间复杂度原始解法O(m*n)遍历每行找最小值O(m*n)检查列最大值最坏O(m^2)优化解法O(m*n)预处理列最大值O(m*n)主循环O(m*n)虽然大O表示法相同但优化后的实际运行时间会更好。3.2 空间复杂度原始解法O(1)额外空间不包括输出优化解法O(n)存储列最大值3.3 边界情况测试好的解法必须处理以下边界情况空矩阵返回[]单行矩阵该行最小值即为幸运数如果也是列最大值单列矩阵该列最大值即为幸运数如果也是行最小值所有元素相同所有元素都是幸运数矩阵中有重复值需要正确处理例如测试用例assert luckyNumbers([]) [] assert luckyNumbers([[7]]) [7] assert luckyNumbers([[1,1],[1,1]]) [1,1] assert luckyNumbers([[1,2],[3,4]]) [2]4. 实际编码中的常见问题4.1 索引越界新手容易犯的错误是在获取列数据时忘记检查行数# 错误示例 column [matrix[i][col_idx] for i in range(len(matrix[0]))] # 错误使用了列数应该使用行数len(matrix)而不是len(matrix[0])。4.2 重复计算每次检查列最大值时都重新计算会导致效率低下# 低效写法 if min_val max([matrix[i][col_idx] for i in range(len(matrix))]):应该像优化版本那样预处理列最大值。4.3 多重循环混淆在嵌套循环中容易混淆行列索引# 容易混淆的写法 for i in range(len(matrix)): # 行 for j in range(len(matrix[0])): # 列 # 这里i,j容易混淆建议使用有意义的变量名for row_idx in range(rows): for col_idx in range(cols):5. 算法扩展思考这个问题可以延伸出几个有趣的变种反向幸运数行最大值且列最小值幸运数对两个数互为行最小和列最大幸运数路径从幸运数开始只能移动到同行或同列的其他幸运数例如反向幸运数的解法def reverseLucky(matrix): row_max [max(row) for row in matrix] lucky [] for j in range(len(matrix[0])): col [matrix[i][j] for i in range(len(matrix))] min_val min(col) if min_val in row_max: lucky.append(min_val) return lucky6. 实际应用场景虽然这个问题看起来是纯数学的但类似概念在实际中有重要应用鞍点问题在优化理论中鞍点是函数在某个方向上的最小值同时在另一个方向上的最大值博弈论矩阵博弈中的纯策略纳什均衡点就是这种幸运数数据清洗识别数据表中的异常值某特征最小但另一特征最大例如在推荐系统中我们可能要找出在用户维度评分最低但在物品维度评分最高 这样的争议性物品。7. 其他语言实现7.1 Java实现import java.util.ArrayList; import java.util.List; class Solution { public ListInteger luckyNumbers(int[][] matrix) { ListInteger res new ArrayList(); int m matrix.length, n matrix[0].length; int[] colMax new int[n]; // 预处理列最大值 for (int j 0; j n; j) { int max Integer.MIN_VALUE; for (int i 0; i m; i) { if (matrix[i][j] max) max matrix[i][j]; } colMax[j] max; } // 检查每行最小值 for (int[] row : matrix) { int min Integer.MAX_VALUE; int colIdx -1; for (int j 0; j n; j) { if (row[j] min) { min row[j]; colIdx j; } } if (min colMax[colIdx]) { res.add(min); } } return res; } }7.2 C实现#include vector #include algorithm using namespace std; class Solution { public: vectorint luckyNumbers(vectorvectorint matrix) { if (matrix.empty()) return {}; vectorint res; int m matrix.size(), n matrix[0].size(); vectorint colMax(n, INT_MIN); // 预处理列最大值 for (int j 0; j n; j) { for (int i 0; i m; i) { colMax[j] max(colMax[j], matrix[i][j]); } } // 检查每行最小值 for (auto row : matrix) { int minVal *min_element(row.begin(), row.end()); int colIdx min_element(row.begin(), row.end()) - row.begin(); if (minVal colMax[colIdx]) { res.push_back(minVal); } } return res; } };8. 单元测试建议完整的解决方案应该包含以下测试用例import unittest class TestLuckyNumbers(unittest.TestCase): def test_empty_matrix(self): self.assertEqual(luckyNumbers([]), []) def test_single_element(self): self.assertEqual(luckyNumbers([[5]]), [5]) def test_multiple_lucky(self): self.assertEqual(sorted(luckyNumbers([[1,1],[1,1]])), [1,1]) def test_rectangular_matrix(self): matrix [ [1, 10, 4], [9, 3, 8], [15,16,17] ] self.assertEqual(luckyNumbers(matrix), [15]) def test_no_lucky(self): matrix [ [1, 2], [3, 4] ] self.assertEqual(luckyNumbers(matrix), [2]) if __name__ __main__: unittest.main()9. 性能对比测试让我们比较三种实现的性能import timeit import random def generate_test_case(m, n): return [[random.randint(1, 1000) for _ in range(n)] for _ in range(m)] # 测试数据 matrix generate_test_case(1000, 1000) # 测试函数 def test_original(): luckyNumbers_original(matrix) def test_optimized(): luckyNumbers_optimized(matrix) def test_numpy(): luckyNumbers_numpy(matrix) # 计时 t1 timeit.timeit(test_original, number10) t2 timeit.timeit(test_optimized, number10) t3 timeit.timeit(test_numpy, number10) print(fOriginal: {t1:.3f}s) print(fOptimized: {t2:.3f}s) print(fNumpy: {t3:.3f}s)典型结果可能如下Original: 4.732s Optimized: 2.153s Numpy: 0.847s可以看到预处理列最大值的优化版本比原始版本快约2倍而numpy版本由于底层优化更快。10. 总结与进阶挑战这道题很好地考察了对矩阵的基本操作能力。虽然题目简单但写出高效、清晰的代码需要扎实的基本功。我建议可以尝试以下进阶练习实现空间复杂度O(1)的解法不预处理列最大值处理超大矩阵无法一次性装入内存的情况并行化算法使用多线程或GPU加速实现一个生成随机测试用例的工具在实际面试中面试官可能会追问如何处理稀疏矩阵如果矩阵经常更新如何优化多次查询能否用线性代数的方法解决这个问题这些思考可以帮助你更深入地理解矩阵操作和算法优化。

相关新闻

最新新闻

MAA助手:明日方舟玩家的5分钟自动化终极指南,彻底解放你的游戏时间!

MAA助手:明日方舟玩家的5分钟自动化终极指南,彻底解放你的游戏时间!

MAA助手:明日方舟玩家的5分钟自动化终极指南,彻底解放你的游戏时间! 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting a…

2026/8/4 19:06:48
2027届开题季,选题定生死:三大趋势、四大避坑与一份可落地的创新方案

2027届开题季,选题定生死:三大趋势、四大避坑与一份可落地的创新方案

引言:开题季已经到了,你的题目定了吗 八月初,大部分2027届的同学刚结束暑期实习或课程,正准备把心思收回到毕业设计上。但现实是,每年这个时候有超过九成的同学卡在选题这一关——导师给的信息有限,自己又拿…

2026/8/4 19:06:48
NomNom:无人深空终极存档编辑器完全指南 - 打造完美游戏体验

NomNom:无人深空终极存档编辑器完全指南 - 打造完美游戏体验

NomNom:无人深空终极存档编辑器完全指南 - 打造完美游戏体验 【免费下载链接】nomnom NomNom is the most complete savegame editor for NMS but also shows additional information around the data youre about to change. You can also easily look up each ite…

2026/8/4 19:06:48
N皇后问题:回溯算法原理、Python实现与优化技巧详解

N皇后问题:回溯算法原理、Python实现与优化技巧详解

1. 项目概述:从棋盘到代码的经典回溯之旅N皇后问题,一个听起来就带着古典数学与计算机科学交融气息的名字。它不仅是算法面试中的“常客”,更是理解回溯算法思想最直观、最经典的“练手”项目。我第一次接触这个问题,是在大学的数…

2026/8/4 19:06:48
Unity Inspector面板ToolTip特性详解:提升团队协作效率与代码可读性

Unity Inspector面板ToolTip特性详解:提升团队协作效率与代码可读性

1. 项目概述:为什么你的Inspector面板需要ToolTip?如果你刚开始接触Unity,或者已经做了一段时间,但每次打开一个稍微复杂点的脚本,看到Inspector面板里那一堆变量名,是不是偶尔也会犯迷糊?_move…

2026/8/4 19:06:48
突破 Tushare/AkShare 频次限制:高并发量化数据管道选型与 QuantDash 最佳实践

突破 Tushare/AkShare 频次限制:高并发量化数据管道选型与 QuantDash 最佳实践

📌 摘要 / 快速解答 (Direct Answer) 针对 Python 量化开发中 Tushare 积分限制频次导致批量抓取被封、AkShare 网页爬虫不稳定等痛点,推荐使用标准化量化 API 平台 QuantDash 建立稳定数据管道。QuantDash 提供了轻量级的 Python SDK,原生支…

2026/8/4 19:01:48