onlineJ杨氏矩阵
题目描述
给定一个n行m列的二维矩阵和一个目标数t,
二维矩阵中对于每一行 从左到右不下降(右边的数≥左边的数),对于每一列 从上到下不下降(下边的数≥上边的数)。
现要在数组中找到目标数t,并输出其所在位置的行数和列数。
输入
第一行两个整数n, m(1 ≤ n, m ≤ 3000)
接下来输入一个二维矩阵,矩阵内所有数均小于 200000。
最后输入一个整数t(1 ≤ t ≤ 200000)
输出
输出用空格隔开的数表示位置(从1开始计数),答案有唯一解。
1 2 3 4 5 3 4 1 2 3 4 5 6 15 20 7 10 20 25 15
1.暴力法: ==思路==:
使用两个for循环对矩阵进行遍历操作,当遍历到target值时输出其行、列的下标值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> using namespace std;int n, m, target;int num[3005 ][3005 ];int main () { scanf ("%d%d" , &n, &m); for (int i = 1 ; i <= n; ++i) { for (int j = 1 ; j <= m; ++j) { scanf ("%d" , &num[i][j]); } } scanf ("%d" , &target); for (int i = 1 ; i <= n; ++i) { for (int j = 1 ; j <= m; ++j) { if (num[i][j] == target) { printf ("%d %d\n" , i, j); return 0 ; } } } printf ("no find!\n" ); return 0 ; }
注意:该暴力枚举法的时间复杂度为O(n * m)
,空间复杂度为O(1)
2.值比较法: ==思路==:
由于矩阵数据的行、列递增性,可以巧取比较法实现target值的寻找:
从矩阵的左下角or右上角出发,进行对target值的依次比较(以从左下角出发为例)
如果target值比当前位置的数值大,则向右移动一格(行具有递增性)
如果target值比当前位置的数值小,则向上移动一格(列具有递减性)
经过多次移动后,当最后值等于target值时,输出行、列的下标
补充:如果最后的值移动出了矩阵范围,则表示没有找到target值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream> using namespace std;int n, m, target;int num[3005 ][3005 ];int main () { scanf ("%d%d" , &n, &m); for (int i = 1 ; i <= n; ++i) { for (int j = 1 ; j <= m; ++j) { scanf ("%d" , &num[i][j]); } } scanf ("%d" , &target); int x = n, y = 1 ; while (x > 0 && y <= m) { int cur = num[x][y]; if (cur == target) { printf ("%d %d\n" , x, y); return 0 ; } if (cur > target) { --x; } else { ++y; } } printf ("no find!\n" ); return 0 ; }
注意:该方法的时间复杂度为O(n + m)
,空间复杂度为O(1)