(每日算法)LeetCode---Search a 2D Matrix(查找元素是否存在)

来源:互联网 发布:软件企业资质证书 编辑:程序博客网 时间:2024/05/18 06:54

通过二分查找查找元素是否存在矩阵中。这也是二分查找的具体应用,思想不变,但是细节上需要变化。

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

  • Integers in each row are sorted from left to right.
  • The first integer of each row is greater than the last integer of the previous row.

For example,

Consider the following matrix:

[  [1,   3,  5,  7],  [10, 11, 16, 20],  [23, 30, 34, 50]]

Given target = 3, return true.

class Solution {public:   bool searchMatrix(vector<vector<int> > &matrix, int target) {  if(matrix.size() == 0)   return false;  int m = matrix.size();int n = matrix[0].size();if(target < matrix[0][0] || target > matrix[m-1][n-1]) //目标元素不在矩阵中return false;int low = 0, high = m - 1;//在行间和行内查找时共用这两个元素,表示当前查找的子范围int medium;while(low <= high )   //通过二分查找确认元素在medium行中{    medium = low + (high - low)/2;if(target < matrix[medium][0]){high = medium - 1;continue;}if(target > matrix[medium][n - 1]){low = medium + 1;continue;}//因为查找的是范围,容易导致while死循环,所以两个条件不满足的时候,//且target不在medium行中的时候,就是target元素不存在,不用再查找了if(matrix[medium][0] <= target && matrix[medium][n - 1] >= target)break;elsereturn false;   }//经过上述步骤能确认target所在的那一行,即medium//接下来在medium行中查找有无targetlow = 0;high = n - 1;while(low <= high )//常规的二分查找{int medium_num = low + (high - low)/2;if(matrix[medium][medium_num] == target)return true;if(matrix[medium][medium_num]  < target)low = medium_num + 1;if(matrix[medium][medium_num] > target)high = medium_num - 1;}return false;    }};

有一种更易懂的方法,如下:

class Solution {public:bool searchMatrix(const vector<vector<int>>& matrix, int target) {if (matrix.empty()) return false;const size_t m = matrix.size();const size_t n = matrix.front().size();//每行元素的数量int first = 0;int last = m * n;while (first < last) {int mid = first + (last - first) / 2;int value = matrix[mid / n][mid % n];//mid所指元素的值if (value == target)return true;else if (value < target)first = mid + 1;elselast = mid;}return false;}};

上面的方法把所有的元素都看做一列,vector本质上也是一维数组的,所以没什么不妥。

第一种方法对所在行也进行二分检索,看似检索的次数比较少,但是要比较两个元素,访问次数也是不低的。

而二分检索的复杂度是对数时间,比较的次数还是比较少的。因此,这里考虑成一维数组还是比较合理的。

效率更高,时间更短。也更好理解。

知识点阐述:

std::vector::front

reference front();const_reference front() const;
Access first element
Returns a reference to the first element in the vector.Unlike member vector::begin, which returns an iterator to this same element, this function returns a direct reference.

Calling this function on an empty container causes undefined behavior.

Return value

A reference to the first element in the vector container.

If the vector object is const-qualified, the function returns a const_reference. Otherwise, it returns a reference.

// vector::front#include <iostream>#include <vector>int main (){  std::vector<int> myvector;  myvector.push_back(78);  myvector.push_back(16);  // now front equals 78, and back 16  myvector.front() -= myvector.back();  std::cout << "myvector.front() is now " << myvector.front() << '\n';  return 0;}
Output:
myvector.front() is now 62





0 0
原创粉丝点击