华为机考真题 -- 最小矩阵宽度

题目描述:

给定一个矩阵,包含 N * M 个整数和一个包含 K 个整数的数组。现在要求在这个矩阵中找一个宽度最小的子矩阵,要求子矩阵包含数组中所有的整数。

输入描述:

第一行输入两个正整数 N,M,表示矩阵大小;
接下来 N 行 M 列表示矩阵内容;
下一行包含一个正整数 K;
下一行包含 K 个整数,表示所需包含的数组,K 个整数可能存在重复数字;

特别注意事项:
所有输入数据小于1000。

输出描述:

输出包含一个整数,表示满足要求子矩阵的最小宽度,若找不到,输出-1。

示例1:

输入
2 5
1 2 2 3 1
2 3 2 3 2
3
1 2 3

输出
2

说明:矩阵第0列和第3列包含了1,2,3,居住第3行和第4行包含了1,2,3,所以输出是2

示例2:

输入
2 5
1 2 2 3 1
2 3 2 3 4
3
1 1 4

输出
5
说明:矩阵第1,2,3,4,5列包含了1,1,4,说以输出是5

C++源码:

#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

int minSubMatrixWidth(const vector<vector<int>>& matrix, const unordered_map<int, int>& nums) {
    int N = matrix.size();
    int M = matrix[0].size();
    int result = -1;

    for (int left = 0; left < M; ++left) {
        unordered_map<int, int> window;
        for (int right = left; right < M; ++right) {
            for (int i = 0; i < N; ++i) {
                if (matrix[i][right] != 0) { // Only consider non-zero elements to match with nums
                    ++window[matrix[i][right]];
                }
            }

            bool allFound = true;
            for (const auto& num : nums) {
                if (window[num.first] < num.second) {
                    allFound = false;
                    break;
                }
            }

            if (allFound) {
                if (result == -1 || right - left + 1 < result) {
                    result = right - left + 1;
                }

                // Correct logic to shrink the window from the left
                for (const auto& num : nums) {
                    --window[num.first]; // Decrease count of the leaving element
                    if (window[num.first] < num.second) {
                        // Restore the count since we've found the point where the condition breaks
                        ++window[num.first];
                        break; // Stop shrinking as soon as any count falls below requirement
                    }
                }

                // Actual shrink after checking all required numbers
                ++left;
            }
        }
    }

    return result;
}

int main() {
    int N, M;
    cin >> N >> M;

    vector<vector<int>> matrix(N, vector<int>(M));
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < M; ++j) {
            cin >> matrix[i][j];
        }
    }

    int K;
    cin >> K;
    unordered_map<int, int> nums;
    for (int i = 0; i < K; ++i) {
        int num;
        cin >> num;
        ++nums[num];
    }

    cout << minSubMatrixWidth(matrix, nums) << endl;

    system("pause");
    return 0;
}

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
华为OD机考真题是指华为公司在招聘过程中所使用的在线机考试题目。这些题目旨在评估应聘者的技术能力、逻辑思维以及解决问题的能力。以下是对华为OD机考真题解读的简要说明。 华为OD机考真题的内容丰富多样,主要涵盖计算机科学、网络技术、算法设计、数据结构等多个领域。对于应聘者来说,这些题目不仅要求具备扎实的专业知识,还要求能够将知识应用于实际场景中,并能够灵活运用、创新思考。 在解答华为OD机考真题时,应聘者需要具备良好的解题思路和方法。首先,应聘者需要仔细阅读题目,理解题意和要求,明确问题的关键点。其次,应聘者需要运用所学知识和技能分析问题,并制定解决方案。此时,良好的逻辑思维和分析能力是十分重要的。最后,应聘者需要将解决方案转化为具体的代码实现或解题步骤,并进行测试和验证。 华为OD机考真题的目的是为了筛选出具备优秀技术能力和解决问题能力的人才。在解题过程中,华为注重考察应聘者的创新能力和解决问题的能力,不仅关注结果,还关注解决问题的思路和方法。因此,应聘者在回答真题时除了要给出正确的答案,还需要展现出对问题的全面思考和独立思考的能力。 总之,华为OD机考真题的解答需要应聘者具备扎实的专业知识、良好的解题思路、逻辑思维能力和解决问题的能力。这些真题旨在筛选出具备创新思维和解决问题能力的优秀人才。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值