【欧拉计划】Q15:杨氏矩阵

杨氏矩阵


  • 递推与递归
  • 原题链接:http://oj.haizeix.com/problem/600

题目描述

给定一个n行m列的二维矩阵和一个目标数t,

二维矩阵中对于每一行从左到右不下降(右边的数≥左边的数),对于每一列从上到下不下降(下边的数≥上边的数)。

现要在数组中找到目标数t,并输出其所在位置的行数和列数。

输入

第一行两个整数n, m(1 ≤ n, m ≤ 3000)

接下来输入一个二维矩阵,矩阵内所有数均小于 200000。

最后输入一个整数t(1 ≤ t ≤ 200000)

输出

输出用空格隔开的数表示位置(从1开始计数),答案有唯一解。

3 4
1 2 3 4
5 6 15 20
7 10 20 25
15
2 3

1.暴力法:

思路

使用两个for循环对矩阵进行遍历操作,当遍历到target值时输出其行、列的下标值。

#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;
}

image-20220504175022611

注意:该暴力枚举法的时间复杂度为O(n * m),空间复杂度为O(1)

2.值比较法:

思路

由于矩阵数据的行、列递增性,可以巧取比较法实现target值的寻找:

  1. 从矩阵的左下角or右上角出发,进行对target值的依次比较(以从左下角出发为例)
  2. 如果target值比当前位置的数值大,则向右移动一格(行具有递增性)
  3. 如果target值比当前位置的数值小,则向上移动一格(列具有递减性)
  4. 经过多次移动后,当最后值等于target值时,输出行、列的下标

补充:如果最后的值移动出了矩阵范围,则表示没有找到target值

image-20220504173136902

#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)

tips:文章部分内容参考算法刷题课程,题解图示内容及代码根据老师课程、以及自己对知识的理解,进行二次整理和部分补充,仅供学习参考使用,不可商业化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值