【刷一刷剑指Offer -- C++】 题目一 -- 二维数组的查找

/*题目描述
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
*/
#include <iostream>
using namespace std;
#include <vector>


class Solution {
public:
    bool Find_1(int target, vector<vector<int> > array) { 
        // 假设数组是个整齐的长方形,不断切除不符合条件的行和列 但这个方法,对于不整齐的数组就失效了 O(N)
int row = array.size();
if (row == 0) return false;
int col = array[0].size();
int i = 0, j = col -1;
while( i < row && j >=0){
if (array[i][j] == target){
return true;
}else if(array[i][j] > target){
j--;
}else{
i++;
}
}
return false;
    }
bool Find_2(int target, vector<vector<int> > array) { 
        // 最古老的办法,数组每行列数不同也可 O(N*N)
if (array.size() == 0){
return false;
}
for(int i = 0; i < array.size(); i ++){
if (array[i].size()==0) continue;
if (target < array[i].front() || target > array[i].back()) continue; // 判断首尾范围,不满足直接跳过
for (int j = 0; j < array[i].size(); j ++){
if (array[i][j] == target) return true;
}
}
return false;
    }
bool Find_3(int target, vector<vector<int> > array) { 
        // Find2的改进版,每一行中采用二分法寻找 NlogN
if (array.size() == 0){
return false;
}
for(int i = 0; i < array.size(); i ++){
if (array[i].size()==0) continue;
if (target < array[i].front() || target > array[i].back()) continue; // 判断首尾范围,不满足直接跳过
if (target == array[i].front() || target == array[i].back()) return true; // 二分法去两头
// 二分法判断
int start = 0; 
int end = array[i].size()-1;
int mid = (start + end)/2;
while(start <= end){
if(target == array[i][mid]){
return true;
}else if (target > array[i][mid]){
start = mid + 1;
}else{
end = mid -1;
}
mid = (start + end)/2;
}
}
return false;
    }
};


int main(){
Solution* sol =  new Solution();
vector<vector <int> > m_vec ( 5, vector<int>(20));
for(int i = 0; i < m_vec.size(); i++){
for (int j=0; j < m_vec[i].size(); j++){
m_vec[i][j] = i*m_vec.size() + 3*j;
cout << m_vec[i][j] << endl;
}
}
cout << sol->Find_3(70,m_vec) << endl;
delete sol;
sol = NULL;
system("pause");
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值