在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
分析
-
方案一:
可以采用传统的方式,使用两个for循环的方式,一个一个的查找 -
方案二:
- 获取二位数组中每行数据
- 针对每行数据进行排序(排序的方法可以采用:冒泡、选择、插入、归并、快排等)我选择的是归并
- 将排好序的每行数据进行二分查找
代码实现
方案一:
public boolean Find(int target, int [][] array) {
// 获取二维数组的列
for (int i = 0; i < array.length; i++) {
// 每列的个数
for (int j = 0; j < array[i].length; j++) {
if (target==array[i][j]){
return true;
}
}
}
return false;
}
方案二:
public boolean Find(int target, int[][] array) {
int temp = 0;
int length =0;
for (int i = 0; i < array.length; i++) {
// 获取每行数组的长度
length = array[i].length;
int[] arr = new int[length];
// 将每行数组进行排序
mergeSort(array[i], 0, length-1, arr);
// 采用二分法查找数据
temp = binarySearch(arr, 0, length-1, target);
if (temp!=-1) {
return true;
}
}
return false;
}
/**
* 分+合的方法
* @param arr 原始的数组
* @param left 左侧有序序列的初始值
* @param right 右侧有序序列索引
* @param temp 中转数组
*/
private void mergeSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2;
// 向左递归进行分解
mergeSort(arr, left, mid, temp);
// 向右递归分解
mergeSort(arr, mid + 1, right, temp);
// 合并
merge(arr, left, mid, right, temp);
}
}
/**
* 合并的方法
*
* @param arr 原始的数组
* @param left 左侧有序序列的初始值
* @param mid 中间值
* @param right 右侧有序序列索引
* @param temp 中转数组
*/
private void merge(int[] arr, int left, int mid, int right, int[] temp) {
System.out.println("===============");
int i = left;// 左侧有序序列的初始值
int j = mid + 1; // 右侧有序序列的初始值
int t = 0; // 中转数组的索引
//把左右两边的数据按照规则填充到temp中
// 直到左右两边的有序数列,其中一边结束为止
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[t] = arr[i];
t++;
i++;
} else {
temp[t] = arr[j];
t++;
j++;
}
}
// 将左侧剩余数组直接拷贝到temp数组
while (i <= mid) {
temp[t] = arr[i];
t++;
i++;
}
// 将右侧剩余数组直接拷贝到temp数组
while (j <= right) {
temp[t] = arr[j];
t++;
j++;
}
// 将temp的数据拷贝到arr
// 注意:并不是每次都拷贝所有
t = 0;
int tempLeft = left;
while (tempLeft <= right) {
arr[tempLeft] = temp[t];
t++;
tempLeft++;
}
}
/**
* 二分查找
* @param arr 数组
* @param left 左边的数组
* @param right 右边的数组
* @param findVal 要查找的数据
* @return
*/
public int binarySearch(int[] arr, int left, int right, int findVal) {
int mid=(left+right)/2;
if (left>right){
return -1;
}
if (findVal>arr[mid]){
mid=binarySearch(arr,mid+1,right,findVal);
}else if(findVal<arr[mid]){
mid=binarySearch(arr,left,mid-1,findVal);
}
return mid;
}
两种方案解析:
第一种方案简单明了,但是运行所耗费时间比第二种多,当数据量越大的时候体现的越明显
第二种方案虽然快,但是耗费空间,因为使用的是递归排序,其特点就是以空间换时间