二维数组的二分查找 解题报告
2012-09-02 22:05
302 查看
【题目大意】
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
【分析】
排好序的一维数组二分查找的效率是O(logN),本例中是二维数组,但是有序的性质可以使得在局部,即一维状况下继续使用二分查找,通过合理的组织查找区间可以再O(NlogM)的时间内找到是否存在该值key。
记二维数组(n行m列)为
则满足 :
A[i][1] <= A[i][2] <= ... <= A[i][m] ( i ∈ [1,n] )
A[1][j] <= A[2][j] <= ... <= A
[j] ( j ∈ [1,m] )
设待查找值可能在第i行,则必有A[i][1] <= key <= A[i][m]
故
①查找key可能在的行,由于在每一列都递增,故可能的行必然连在一起,即为一个区间[top,down],在这个区间有A[i][1] <= key <= A[i][m] ( i ∈ [top,down] )
通过二分查找可得出满足要求的[top,down]
②从第top行开始查找值key,一行一行往下搜,知道down的下一行或者搜到结果。采用如下搜法:
即当前在第cur行,在cur行的搜索区间为[left,right]( A[cur][left] <= key <= A[cur][right] )。
找到cur行在[left,right]区间中<=key的最大值的位置pos,若其==key,则返回找到,否则key不可能在本行,只可能在下面若干行中。
比较 A[cur+1][pos] 和 key
若其>key,则搜索区间为第cur+1行的[left,pos-1]。
若其 <key,则搜索区间为第cur+1行的[pos+1,key]。
否则找到。
如此往下搜,直到找到或者cur==down+1终止。
由上可知复杂度为O(nlogn)。
给个oj的链接:点击打开链接
附个代码:
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
【分析】
排好序的一维数组二分查找的效率是O(logN),本例中是二维数组,但是有序的性质可以使得在局部,即一维状况下继续使用二分查找,通过合理的组织查找区间可以再O(NlogM)的时间内找到是否存在该值key。
记二维数组(n行m列)为
A11 | A12 | …… | A1n |
…… | …… | …… | …… |
An1 | An2 | …… | Anm |
A[i][1] <= A[i][2] <= ... <= A[i][m] ( i ∈ [1,n] )
A[1][j] <= A[2][j] <= ... <= A
[j] ( j ∈ [1,m] )
设待查找值可能在第i行,则必有A[i][1] <= key <= A[i][m]
故
①查找key可能在的行,由于在每一列都递增,故可能的行必然连在一起,即为一个区间[top,down],在这个区间有A[i][1] <= key <= A[i][m] ( i ∈ [top,down] )
通过二分查找可得出满足要求的[top,down]
②从第top行开始查找值key,一行一行往下搜,知道down的下一行或者搜到结果。采用如下搜法:
即当前在第cur行,在cur行的搜索区间为[left,right]( A[cur][left] <= key <= A[cur][right] )。
找到cur行在[left,right]区间中<=key的最大值的位置pos,若其==key,则返回找到,否则key不可能在本行,只可能在下面若干行中。
比较 A[cur+1][pos] 和 key
若其>key,则搜索区间为第cur+1行的[left,pos-1]。
若其 <key,则搜索区间为第cur+1行的[pos+1,key]。
否则找到。
如此往下搜,直到找到或者cur==down+1终止。
由上可知复杂度为O(nlogn)。
给个oj的链接:点击打开链接
附个代码:
#include <cstdlib> #include <string.h> #include <vector> #include <set> #include <iostream> #include <stdio.h> #include <queue> using namespace std; const int maxn = 1024 ; int matrix[maxn][maxn] , n , m , key ; inline bool get(int &t) { bool flag = 0 ; char c; while(!isdigit(c = getchar())&&c!='-') if( c == -1 ) break ; if( c == -1 ) return 0 ; if(c=='-') flag = 1 , t = 0 ; else t = c ^ 48; while(isdigit(c = getchar())) t = (t << 1) + (t << 3) + (c ^ 48) ; if(flag) t = -t ; return 1 ; } /*返回第一个<=key的元素*/ int bs(int array[],int l,int r) { int mid ; while (l<=r) { mid = (l+r) >> 1 ; if( array[mid] > key ) r = mid-1 ; else l = mid+1 ; } return r ; } bool query() { int topRow , downRow , i , j , l , r , mid , temp ; l = 0 ; r = n-1 ; /*找第一个<=key的*/ while (l<=r) { mid = (l+r) >> 1 ; if( matrix[mid][0] > key ) r = mid-1 ; else l = mid+1 ; } //[0,r] if( r == -1 ) return false ; if( matrix[r][0] == key ) return true ; temp = r ; l = 0 ; r = n-1 ; /*找第一个>=key的*/ while (l<=r) { mid = (l+r) >> 1 ; if( matrix[mid][m-1] >= key ) r = mid-1 ; else l = mid+1 ; } //[l,n-1] if( l == n ) return false ; if( matrix[l][m-1] == key ) return true ; r = temp ; /*[0,r]和[l,n-1]无交集*/ if( r < l ) return false ; topRow = l ; downRow = r ; /*interval is[topRow,downRow]*/ l = 0 ; r = m-1 ; for ( i = topRow ; i <= downRow ; i++) { j = bs(matrix[i],l,r); if( matrix[i][j] == key ) return true ; if( i < downRow ) { if( matrix[i+1][j] > key ) r = j ; else if( matrix[i+1][j] < key ) l = j ; else return true ; } } return false ; } int main() { int i , j , k ; while(get(n)) { get(m); get(key); for ( i = 0 ; i < n ; i++) for( j = 0 ; j < m ; j++) get(matrix[i][j]); printf("%s\n",query()?"Yes":"No"); } }
相关文章推荐
- 2017青岛ACM网络赛解题报告——hdu 6216 二分查找
- 二分查找——C:Sacrament of the sum 解题报告
- 二分查找——D:Pie 解题报告
- 剑指offer第一题:二维数组中的查找解题报告
- 【剑指Offer】二维数组中的查找 解题报告(Java & Python)
- 二分或三分查找:C - Strange fuction 解题报告
- 【原】 POJ 1056 IMMEDIATE DECODABILITY Trie树查找前缀 解题报告
- POJ2112解题报告【网络流-初级-isap+floyd_warshall+二分】
- UVA11090 Going in Cycle!! 解题报告【判负环】【SPFA】【二分答案】
- POJ3525/LA3890 Most Distant Point from the Sea 解题报告【计算几何】【二分答案】【半平面交】
- 【九度OJ】题目1173:查找 解题报告
- 【九度OJ】题目1176:树查找 解题报告
- 洛谷 1083||NOIP 2012 借教室 二分答案+差分 解题报告
- PHP-----二维数组和二分查找
- UVa 1450 Airport 解题报告(二分+策略)
- BZOJ 2732 二分+半平面相交 解题报告
- SPOJ 287 网络流最大流+二分答案 解题报告
- LeetCode #28. Implement strStr() 子串查找 解题报告
- [算法][LeetCode]Search a 2D Matrix——二维数组的二分查找
- 解题报告 数字查找