剑指 Offer 04. 二维数组中的查找
- 思路:比较target和每行第一个元素、最后一个元素之间的大小关系,找到target对应所在的行,然后在该行内查找即可;
- 在行内查找就可以使用多种思路了,顺序或者折半等等;
顺序查找的代码:
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
int rows = matrix.size();
if(rows == 0)
{
return false;
}
int cols = matrix[0].size();
if(cols == 0)
{
return false;
}
for(int i = 0;i<rows;i++)
{
if(target>=matrix[i][0]&&target<=matrix[i][cols-1])
{
for(int j = 0;j<cols;j++)
{
if(matrix[i][j] == target)
{
return true;
}
}
}
}
return false;
}
};
折半查找的代码:
class Solution {
public:
bool binarySearch(vector<int>& nums,int data)
{
int low = 0;
int high = nums.size()-1;
int mid = 0;
while(low<=high)
{
mid = (low+high)/2;
if(nums[mid]>data)
{
high = mid - 1;
}
else if(nums[mid]<data)
{
low = mid +1;
}
else
{
return true;
}
}
return false;
}
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
int rows = matrix.size();
if(rows == 0)
{
return false;
}
int cols = matrix[0].size();
if(cols == 0)
{
return false;
}
for(int i = 0;i<rows;i++)
{
if(target>=matrix[i][0]&&target<=matrix[i][cols-1])
{
if(binarySearch(matrix[i],target))
{
return true;
}
}
}
return false;
}
};
做的过程中,看见了一篇博客中介绍了插值查找,顺便bia在这里,以后看还方便;
下面是借鉴的原博客中内容:
- 基本思想:插值查找也是基于二分查找,把查找点的选择改进为自适应选择,从而提高查找的效率。当然,差值查找也属于有序查找。
- 注意:对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多。但是,数组中元素如果分布非常不均匀,那么插值查找未必是很合适的选择。
- 复杂度分析:查找成功或者失败的时间复杂度均为O(log2(log2n))。
//插值查找
int InsertionSearch(int a[], int value, int low, int high)
{
int mid = low+(value-a[low])/(a[high]-a[low])*(high-low);
if(a[mid]==value)
return mid;
if(a[mid]>value)
return InsertionSearch(a, value, low, mid-1);
if(a[mid]<value)
return InsertionSearch(a, value, mid+1, high);
}
//或者
//插值查找
bool InsertionSearch(vector<int>& nums, int value, int low, int high)
{
int mid = 0;
while(low<high)
{
mid = low+(value-nums[low])/(nums[high]-nums[low])*(high-low);
if(nums[mid]==value)
{
return true;
}
if(nums[mid]>value)
{
high = mid-1;
}
if(nums[mid]<value)
{
low = mid + 1;
}
}
return false;
}
安利一位前辈的博客:
Poll的笔记