题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
例如:下面的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字7,则返回true;如果查找数字5,由于数组不含有该数字,则返回false。
解题思路
看到该题目想到的最简单暴力做的做法就是直接遍历数组查找。但是实际上一般都要用效率更高的做法,该题目有两个重要条件,从左到右递增,从上到下递增,也就是说每一个数都比前一个大比后一个小,比上面的大比下面的小。由此想到可以右上角或者左下角开始处理,这样每次处理都会剔除一行或者一列,逐渐缩小范围,直到找到要查找的数字或者没有。
代码实现
/// <summary> /// 检测是否在数组范围内 /// </summary> /// <param name="array"></param> /// <param name="target"></param> /// <returns></returns> private static bool CheckIsArrayRange(int[,] array, int target) { bool result = false; if (array != null && array.Rank == 2) { int rowLength = array.GetLength(0); int colLength = array.GetLength(1); int start = array[0, 0]; int end = array[rowLength - 1, colLength - 1]; if (start <= target && target <= end) { result = true; } } return result; } /// <summary> /// 暴力解法-直接遍历 /// </summary> /// <param name="array">数组</param> /// <param name="target">目标</param> /// <returns></returns> private static bool FindForSimple(int[,] array, int target) { bool result = false; if (CheckIsArrayRange(array, target)) { foreach (var item in array) { if (target == item) { result = true; break; } } } return result; } /// <summary> /// 右上角解题 /// </summary> /// <param name="array"></param> /// <param name="target"></param> /// <returns></returns> private static bool FindForRight(int[,] array, int target) { bool result = false; if (CheckIsArrayRange(array, target)) { int rowLength = array.GetLength(0); int colLength = array.GetLength(1); int row = 0, col = colLength - 1;//坐标右上角 while (row < rowLength && col >= 0) { if (array[row, col] == target) { result = true; break; } else if (array[row, col] > target) { col--; } else { row++; } } } return result; }
想入非非:扩展思维,发挥想象
目的:
1. 熟悉二维数组
2. 不要动不动就循环,多想想
扩展:
1. 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增n的顺序排序,每一列都按照从上到下递增n的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
解题思路:从左到右递增n,从上到下递增n,这属于等比递增数组(自己起的),这样的如果还用右上角的做法,那效率不是很高,正确的做法是用等比数列计算求值的方法。(target-start)/n,如果可以整除,那么这个数据就存在,不能整除就不存在。
代码实现
/// <summary> /// 等比数列的数组 /// </summary> /// <param name="array"></param> /// <param name="target"></param> /// <returns></returns> private static bool FindForN(int[,] array, int target) { bool result = false; if (CheckIsArrayRange(array, target)) { int rowLength = array.GetLength(0); int colLength = array.GetLength(1); int first = array[0, 0]; int second = 0; if (rowLength > 1) { second = array[1, 0]; } else if (colLength > 1) { second = array[0, 1]; } else { second = target; } int n = second - first; if (n == 0) { if (first == target) { result = true; } } else { int remainder = (target - first) % n; if (remainder == 0) { result = true; } } } return result; }
2. 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数,有返回数据的坐标
解题思路:按照右上角的解题思路,把坐标记录放到list中就可以了。
测试

[Fact] public void Test1() { int[,] array = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } }; int target = 4; Assert.True(Coding001.FindForSimple(array, target)); Assert.True(Coding001.FindForRight(array, target)); } [Fact] public void Test3() { int[,] array = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } }; int target = 3; Assert.False(Coding001.FindForSimple(array, target)); Assert.False(Coding001.FindForRight(array, target)); } [Fact] public void MinTest() { int[,] array = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } }; int target = 0; Assert.False(Coding001.FindForSimple(array, target)); Assert.False(Coding001.FindForRight(array, target)); } [Fact] public void MaxText() { int[,] array = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } }; int target = 16; Assert.False(Coding001.FindForSimple(array, target)); Assert.False(Coding001.FindForRight(array, target)); } [Fact] public void Test5() { int[,] array = { { 1, 2, 3, 4 }, { 2, 3, 4, 5 }, { 3, 4, 5, 6 } }; int target = 3; Assert.True(Coding001.FindForSimple(array, target)); Assert.True(Coding001.FindForRight(array, target)); Assert.True(Coding001.FindForN(array, target)); } [Fact] public void Test6() { int[,] array = { { 1, 2, 3, 4 }, { 2, 3, 4, 5 }, { 3, 4, 5, 6 } }; int target = 7; Assert.False(Coding001.FindForSimple(array, target)); Assert.False(Coding001.FindForRight(array, target)); Assert.False(Coding001.FindForN(array, target)); } [Fact] public void Test7() { int[,] array = { { 1, 3, 5, 7 }, { 3, 5, 7, 9 }, { 5, 7, 9, 11 } }; int target = 9; Assert.True(Coding001.FindForSimple(array, target)); Assert.True(Coding001.FindForRight(array, target)); Assert.True(Coding001.FindForN(array, target)); } [Fact] public void Test8() { int[,] array = { { 1, 3, 5, 7 }, { 3, 5, 7, 9 }, { 5, 7, 9, 11 } }; int target = 8; Assert.False(Coding001.FindForSimple(array, target)); Assert.False(Coding001.FindForRight(array, target)); Assert.False(Coding001.FindForN(array, target)); }
结果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2016-07-03 C#高级功能(四)扩展方法和索引
2016-07-03 C#高级功能(三)Action、Func,Tuple