当前位置:网站首页>spiral matrix visit Search a 2D Matrix
spiral matrix visit Search a 2D Matrix
2022-06-13 00:56:00 【bitcarmanlee】
最近看到几道与矩阵有关的题,觉得有点意思,思路也是挺有代表性,特意进行记录。
1.spiral matrix
对矩阵进行螺旋遍历,也是一个经典场景了,leetcode54题就是这个,给个示意图就清楚了。
解题思路是:设立left,right,up,down四个量表示四条边的起始位置,然后沿着四条边进行遍历。需要注意的是退出条件。
#include<iostream>
#include<vector>
using namespace std;
void run() {
vector<vector<int>> nums = {
{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
int left=0, right=nums[0].size()-1, up=0, down=nums.size()-1;
while(true) {
for(int i=left; i<=right; i++) {
cout<<nums[up][i]<<" ";
}
up++;
if(up>down) break;
for(int i=up; i<=down; i++) {
cout<<nums[i][right]<<" ";
}
right--;
if (right<left) break;
for(int i=right; i>=left; i--) {
cout<<nums[down][i]<<" ";
}
down--;
if (down<up) break;
for(int i=down; i>=up; i--) {
cout<<nums[i][left]<<" ";
}
left++;
if (left>right) break;
}
}
int main(int argc, char const *argv[])
{
run();
return 0;
}
对照上面的代码:
先从left->right进行遍历,相当于遍历上面的一条边。遍历结束后,对up进行加1操作。并且进行判断,如果此时up>down,说明遍历已经完成,循环结束。
其他三条边遍历逻辑类似,注意写代码的时候稍微小心仔细一些即可。
2.Search a 2D Matrix
leetcode第74题是Search a 2D Matrix。
题目要求是
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。
要求是高效算法,同时又是各种有序,很容易想到使用二分查找。
最先想到的思路:因为每行元素有序,所以直接对每行数据进行二分查找是很自然的想法。
对一行数据进行二分查找,复杂度log(n),总共有m行,所以总复杂度为mlog(n)。
上面的解法,应用了每行有序的性质,但是忽略了矩阵整体有序的性质。所以更优秀的解法是利用矩阵整体有序的性质,先确定数据可能在哪一行,再对该行进行二分查找。
#include<iostream>
#include<vector>
using namespace std;
pair<bool, int> binary_search_last_less(vector<vector<int>> &vec, int left, int right, int target) {
int n = right;
while(left <= right) {
int mid = (left+right)/2;
int num = vec[mid][0];
if (num == target) {
return make_pair(true, mid);
} else if(num > target) {
right = mid - 1;
} else {
if (mid == n || vec[mid+1][0] > target) return make_pair(false, mid);
else left = mid + 1;
}
}
return make_pair(false, -1);
}
int binary_search(vector<int> &nums, int left, int right, int target) {
while(left <= right) {
int mid = (left+right)/2;
if (nums[mid] < target) {
left = mid+1;
} else if (nums[mid] > target) {
right = mid-1;
} else {
return mid;
}
}
return -1;
}
pair<int, int> search(vector<vector<int>> &vec, int target) {
int m=vec.size(), n=vec[0].size();
pair<bool, int> ret = binary_search_last_less(vec, 0, m-1, target);
if (ret.first) return make_pair(ret.second, 0);
int row = ret.second;
if (row == -1) return make_pair(-1, -1);
int column = binary_search(vec[row], 0, n-1, target);
if (column == -1) return make_pair(-1, -1);
else return make_pair(row, column);
}
int main(int argc, char const *argv[])
{
vector<vector<int>> vec = {
{1,3,5,7}, {10,11,16,20}, {23,30,24,60}};
int target = 60;
pair<int, int> result = search(vec, target);
cout<<result.first<<" "<<result.second<<endl;
return 0;
}
上面的代码看着好像很长,其实逻辑比较清晰。
binary_search_last_less方法,搜索对象是矩阵的第一列,判断target是否在一列。如果不在第一列,则target一定位于最后一个小于target的那一行(如果存在的话)。
binary_search则是经典的二分查找,查找对象是target可能位于的那一行。
search方法是判断各种情况。
1.如果target位于第一列,直接返回结果
2.target不在第一列,并且最后一个小于target的第一列元素行索引为-1,说明矩阵的所有数据都大于target,返回结果。
3.最后一个小于target的第一列元素行索引不为-1,则对该行进行二分查找,最后返回结果。
根据上面的解析,是不是思路就特别清晰了已经。
3.Search a 2D Matrix II
leetcode 240题是另外一个版本的矩阵搜素。题目要求为
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
因为每行、每列元素都有序,所以我们针对每行/每列进行二分搜索也是可以的。
下面我们提供另外一种思路来解。
如果我们从右上角进行遍历,向左数字会变小,向下数字会变大,有点和二分查找树相似
所以我们可以把 target 和当前值比较。
如果 target 的值大于当前值,那么就向下走。
如果 target 的值小于当前值,那么就向左走。
如果相等就返回。
向下走,等于丢弃当前行;向左走,等于丢弃当前列,这样就起到了加速的作用。
#include<iostream>
#include<vector>
using namespace std;
pair<int, int> search(vector<vector<int>> &vec, int target) {
int m = vec.size(), n = vec[0].size();
int x = 0, y = n-1;
while(x <= m-1 && y >= 0) {
if (vec[x][y] > target) {
y--;
} else if (vec[x][y] < target) {
x++;
} else {
return make_pair(x, y);
}
}
return make_pair(-1, -1);
}
void run() {
vector<vector<int>> vec = {
{1,4,7,11,15},{2,5,8,12,19},{3,6,9,16,22},{10,13,14,17,24},{18,21,23,26,30}};
int target = 20;
auto result = search(vec, target);
cout<<result.first<<" "<<result.second<<endl;
}
int main(int argc, char const *argv[])
{
run();
return 0;
}
边栏推荐
- ROS从入门到精通(零) 教程导读
- 什么是 dummy change?
- With a market value of more than trillion yuan and a sales volume of more than 100000 yuan for three consecutive months, will BYD become the strongest domestic brand?
- Quantitative investment traditional index investment decision vs Monte Carlo simulation method
- Unity calls alertdialog
- pytorch和tensorflow有什么区别?
- 阿姨学代码续集:能力吊打大批程序员
- Rest at home today
- gpu加速pytorch能用吗?
- Influence of higher order poles on waveform
猜你喜欢
Et5.0 simply transform referencecollectorieditor
高阶极点对于波形的影响
Today's sleep quality record 74 points
Breadth first search for node editor runtime traversal
Can GPU acceleration pytorch work?
Expression tree - medium order printout
How many steps are appropriate for each cycle of deep learning?
Kotlin coroutine suspend function suspend keyword
Quantitative investment traditional index investment decision vs Monte Carlo simulation method
Illustrator tutorial, how to add dashes and arrows in illustrator?
随机推荐
Self use notes for problem brushing learning
[JS component] previous queue prompt
[virtual machine] notes on virtual machine environment problems
[JS component] create a custom horizontal and vertical scroll bar following the steam style
STM32 USB Basics
单片机串口中断以及消息收发处理——对接受信息进行判断实现控制
Unity calls alertdialog
[JS component] dazzle radio box and multi box
Notes: the 11th and 12th generation mobile versions of Intel support the native thunderbolt4 interface, but the desktop version does not
Unity extension
What is dummy change?
Et5.0 simply transform referencecollectorieditor
Three threads print digital demo alternately
Hard (magnetic) disk (II)
什么是 Meebits?一个简短的解释
In / out / inout details of MySQL stored procedures
Go simple read database
Canvas random bubbling background
sort
[server data recovery] successful cases of data loss recovery during data migration between storage servers