这几天在Iteye看到有个有奖问答的题目,二维数组的二分查找。想想最近也没什么事情,就做了一下。自己的算法基础很是薄弱,所以也参考了一些网上的东东。那个有奖什么就不参加了。哈哈。。。。
原题如下(估计很多人知道了):
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
例如下面的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字7,则返回true;如果查找数字5,由于数组不含有该数字,则返回false。
我这里主要讲下我当时是怎么做的
。
我的第一印象如果想快速的查找的话应该要利用到对角线。因为对角线元素在他所在的矩阵中最大的,可以在一定程度缩小查找范围。但当时没有具体想清楚该怎么做。后来又想到题目中没有指定数组是N*N的,所以先放弃了这个想法。然后继续想想,如果面试官问我这个题目的话该怎么做。
首先当然是保证不错,二重遍历是肯定不会错的。我都一个一个比较了还会有什么问题呢。当然这个就跟别人问你用什么方法排序的,你回答冒泡排序一样,没什么技术含量。不过至少说明你了解了题目的内容。
再深入一下,二维数组是数组的数组。一般对于有序数组可以采用二分法对数组进行一个lgn的查找。那这样可以对二维数组的每个数组进行一次二分查找。这样就比较不错了,知道了二分查找。估计可以打个及格的分数了。
继续深入,可能就会像我一样想到了利用对角线。但是这个要考虑到不是N*N的情况。利用对角线对矩阵分块,然后就可以排除一些数据了。类如上图中,查找元素 7.跟对角线元素比较之后, 4 < 7 < 10, 那就说明,4左上角,10右下角的数据不用处理。就减少了一半的数据。这篇文章很清楚的说明了这种方法应该怎么做。
http://justjavac.iteye.com/blog/1310178
做到这一步以后,我是没什么办法了。如果面试官问我,还有更好的办法没。我就只能拜拜了。不过,好的方法总是有的,只要好好的寻找。我在网上搜索的时候发现了杨氏矩阵查找的方法。
http://blog.csdn.net/michealmeng555/article/details/2489923
杨氏矩阵查找跟对角线的方法差不多,但是不是用的主对角线\,而是用的副对角线/. 在副对角线中的元素有个性质。在以他为左右两个顶点的矩阵中,他是一个数组中的最大值,是另外一个数组中的最小值。那我们可以利用这个性质,假设我们选择最右上角的元素 a。那么对于需要查找的元素b,如 a > b 向左走,如果 a < b向下走。直到到达最左下角结束。真是太精妙了。
其实这些算法都不是很难,难的是能够想到。如果没想到,那就尽快的学起来吧。。。
public class Search2Array {
private static int[][] arrays = {{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}};
//最容易的办法,使用两重循环
//复杂度O(n2)
public static boolean search1(int target){
for(int[] arr : arrays){
for(int a : arr){
if (a == target){
return true;
}
}
}
return false;
}
//对每个子一维数组用二分查找
//复杂度为O(nlgn)
public static boolean search2(int target){
boolean flag = false;
for(int [] arr : arrays){
flag = binarySearch(arr, 0, arr.length -1, target);
if(flag){
return true;
}
}
return false;
}
//二分查找
private static boolean binarySearch(int[] array, int start, int end, int target){
int middle = start + (end - start)/2;
while(start <= end){
if(array[middle] == target){
return true;
}else if(array[middle] > target){
end = middle - 1;
}else {
start = middle + 1;
}
middle = start + (end - start)/2;
}
return false;
}
//使用最右上角或者最左下角的元素作为起始元素
//这两个位置的元素有个性质:是一个数组中最大的,也是一个数组中最小的
//纵向也看做一个数组
//复杂度为O(m+n)
public static boolean youngTableau(int target){
int raw = 0;
int col = arrays[0].length - 1;
while(col >= 0 && raw <= arrays.length -1){
int tmp = arrays[raw][col];
if( tmp == target){
return true;
}else if(tmp > target) {
col--;
}else{
raw++;
}
}
return false;
}
public static void main(String[] args){
System.out.println(search1(7));
System.out.println(search1(5));
System.out.println(search2(7));
System.out.println(search2(5));
System.out.println(youngTableau(7));
System.out.println(youngTableau(5));
}
}
- 大小: 6.4 KB
分享到:
相关推荐
在C#编程中,动态二维数组是一种非常重要的数据结构,特别是在处理不定数量的数据或需要灵活扩展数据表的情况下。本文将深入探讨动态二维数组的概念、创建方法、操作技巧以及其在实际编程中的应用。 动态二维数组,...
本文将详细讲解易语言中二维数组的赋值方法,并通过实例源码帮助你深入理解这一概念。 二维数组,顾名思义,是具有两个索引维度的数组,可以看作是由若干个一维数组排列而成的一个矩形阵列。在易语言中,二维数组...
本教程将重点讲解如何使用C++将一维和二维数组的数据写入文本文件(txt),以及如何从txt文件中读取数据并存储到一维和二维数组中。数组在C++中是基本的数据结构,而指针则为动态操作提供了便利。以下是一些关键知识...
在LabVIEW编程环境中,二维数组是一种常见的数据结构,用于存储多行多列的数据。本教程将深入探讨如何在LabVIEW中有效地读取二维数组的所有数据,这对于数据分析、处理和可视化至关重要。 首先,让我们理解二维数组...
在C#编程中,二维数组是一种常见的数据结构,用于存储多列或多行的数据。当处理这类数据时,可能需要对数组中的元素进行排序,以便于分析或展示。本篇文章将详细探讨如何在C#中实现对二维数组的排序,特别关注如何...
本编程练习旨在加深对C语言中二维数组、指针和函数的理解,通过实际操作提升编程技能。下面我们将深入探讨这些知识点。 首先,二维数组在C语言中被声明为`类型名 数组名[行数][列数]`,例如`int arr[3][4]`创建了一...
- 相反地,使用双层循环将一维数组中的元素按照原始二维数组的结构重新分配。 - 示例代码片段: ```c for (int y = 0; y ; y++) { for (int z = 0; z ; z++) { a[y][z] = b[y * 3 + z]; // 关键步骤 } } ``...
一维数组转二维数组
在C#编程中,一维数组到二维数组的转换是一个常见的操作,特别是在处理表格数据或者在Windows Forms(WinForm)应用程序中创建控件布局时。本篇将详细讲解如何进行这种转换以及如何保存二维数组的数据。 首先,让...
例如,如果你有一个C++函数接收二维数组并返回二维数组,你可以这样在Java中定义: ```java public interface MyDLL extends Library { // 定义C++函数原型 int processArray(int[][] input, int[][] output); } ...
二维数组中的查找,逐行扫描,行内使用二分查找。最差情况需要扫描所有行,待完善
C# json 一维数组 和 二维数组的转换 写的非常详细,对大家有帮助
将labview内二维数组方便的转化为一维数组使用
在C++编程中,处理二维数组是常见的任务之一,特别是在数据处理、图像处理等领域。本文将详细介绍如何在C++中找到二维数组中的最大值和最小值。首先,我们需要理解二维数组的基本概念。二维数组可以看作是一组一维...
搜索字符串二维数组时,我们可能要寻找特定的字符串是否存在于数组中,或者查找包含特定子串的所有行或列。 1. **创建自定义搜索函数**:由于LabVIEW没有内置的二维数组搜索函数,我们需要自定义VI(虚拟仪器)来...
在"20.5 使用两个一维数组构造二维数组.xls"文件中,我们可以看到具体的示例和步骤。通过这个例子,你将学会如何灵活运用Excel的数组公式,处理和分析多维度的数据,这对于数据分析和报表制作等工作来说非常有用。 ...
在C++编程中,二维数组是一种非常常见的数据结构,它被广泛用于表示表格或矩阵等数据。本篇文章将深入探讨如何将二维数组作为函数的形参进行传递,以实现特定的功能,例如本例中的二维数组求和。我们将讨论两种主要...
// 二维数组冒泡排序 public static void main(String[] args) { int i=0, j=0, temp = 0; int[][] nums1 = { { 34, 1, 22, 5 }, { 28, 98, 15, 32 }, { 33, -5, 17, 41 } }; int rows = nums1.length; //二维...
C语言中二维数组作为函数参数来传递的三种方法 在C语言中,二维数组作为函数参数来传递是非常常见的操作。但是,如何正确地传递二维数组作为函数参数却是许多初学者和开发者经常混淆的地方。今天,我们将详细介绍...
此外,易语言的源码中可能会包含更复杂的二维数组操作,比如数组的遍历、查找、排序等。在易语言资源论坛上,你可以找到许多关于二维数组应用的实例和技巧,这对于提升易语言编程技能非常有帮助。 标签中的"SanYe...