一:程序的主题
1.题目:
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
2.自己写的程序
1 package com.jianke.it; 2 3 public class FindNumFromTwoArray { 4 /* 5 [1,2,8,9], 6 [2,4,9,12], 7 [4,7,10,13], 8 [6,8,11,15] 9 */ 10 public static void main(String[] args) { 11 long start=System.nanoTime(); 12 int array[][]={{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}}; 13 int target=7; 14 boolean flag=Find(target,array); 15 long end=System.nanoTime(); 16 System.out.println("boolean="+flag); 17 System.out.println("spend time:"+(end-start)+"ns"); 18 } 19 public static boolean Find(int target, int [][] array) { 20 boolean flag=false; 21 int count=array.length; 22 for(int i=0;i<count;i++) { 23 for(int j=0;j<array[i].length;j++) { 24 if(target==array[i][j]) { 25 return true; 26 } 27 } 28 } 29 return flag; 30 } 31 32 }
3.结果
4.程序二
/* 思路
* 矩阵是有序的,从左下角来看,向上数字递减,向右数字递增,
* 因此从左下角开始查找,当要查找数字比左下角数字大时。右移
* 要查找数字比左下角数字小时,上移
*/
1 package com.jianke.it; 2 3 public class FindNumFromTwoArray { 4 /* 5 [1,2,8,9], 6 [2,4,9,12], 7 [4,7,10,13], 8 [6,8,11,15] 9 */ 10 public static void main(String[] args) { 11 long start=System.nanoTime(); 12 int array[][]={{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}}; 13 int target=7; 14 boolean flag=Find(target,array); 15 long end=System.nanoTime(); 16 System.out.println("boolean="+flag); 17 System.out.println("spend time:"+(end-start)+"ns"); 18 } 19 public static boolean Find(int target, int [][] array) { 20 int len=array.length-1; 21 int i=0; 22 while(len>=0&&(array[0].length>i)) { 23 if(array[len][0]>target) { 24 len--; 25 }else if(array[len][i]<target){ 26 i++; 27 }else { 28 return true; 29 } 30 } 31 return false; 32 } 33 34 }
5.程序三
/*思路
*把每一行看成有序递增的数组,
*利用二分查找,
*通过遍历每一行得到答案,
*时间复杂度是nlogn
*/
1 package com.jianke.it; 2 3 public class FindNumFromTwoArray { 4 /* 5 [1,2,8,9], 6 [2,4,9,12], 7 [4,7,10,13], 8 [6,8,11,15] 9 */ 10 public static void main(String[] args) { 11 long start=System.nanoTime(); 12 int array[][]={{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}}; 13 int target=7; 14 boolean flag=Find(target,array); 15 long end=System.nanoTime(); 16 System.out.println("boolean="+flag); 17 System.out.println("spend time:"+(end-start)+"ns"); 18 } 19 public static boolean Find(int target, int [][] array) { 20 for(int i=0;i<array.length;i++) { 21 int low=0; 22 int high=array[i].length-1; 23 while(low<=high) { 24 int mid=(low+high)/2; 25 if(target<array[i][mid]) { 26 high=mid-1; 27 }else if(target>array[i][mid]) { 28 low=mid+1; 29 }else { 30 return true; 31 } 32 } 33 } 34 return false; 35 } 36 37 }
二:思考
1.为什么从左下角开始查找
为什么不从左上角开始搜寻,左上角向右和向下都是递增,那么对于一个点,对于向右和向下会产生一个岔路;
如果我们选择从左下脚开始搜寻的话,如果大于就向右,如果小于就向下
2.时间复杂度
法1:从左下搜索,遇大上移,遇小右移,时间复杂度O(m+n)
法2:每行都进行二分查找,时间复杂度O(mlogn)