华为OD统一考试 - 最小矩阵宽度

题目描述

给定一个矩阵,包含 N * M 个整数,和一个包含 K 个整数的数组。

现在要求在这个矩阵中找一个宽度最小的子矩阵,要求子矩阵包含数组中所有的整数。

输入描述

第一行输入两个正整数 N,M,表示矩阵大小。

接下来 N 行 M 列表示矩阵内容。

下一行包含一个正整数 K。

下一行包含 K 个整数,表示所需包含的数组,K 个整数可能存在重复数字。

所有输入数据小于1000。

输出描述

输出包含一个整数,表示满足要求子矩阵的最小宽度,若找不到,输出-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 5

1 2 2 3 1

1 3 2 3 4

3

1 1 4

输出

5

说明

矩阵第1、2、3、4、5列包含了1、1、4

题目解析

本题其实就是“最小覆盖子串”问题的变形。关于最小覆盖子串问题,

当了解了最小覆盖子串问题后,本题中各个关键词可以类比到最小覆盖子串问题中的关键词:

当前题目

最小覆盖子串问题

矩阵matrix

主串s

矩阵matrix的每一列col列数组

主串s的每个字符c

K个元素目标数组nums

目标串t

求含有nums数组所有元素的最小宽度子矩阵

求含有目标串t所有字符的最小覆盖子串

因此,本题可以使用尺取法高效地求出满足要求地子矩阵地最小宽度。

import Foundation

func ODTest_2_19() {
    print("输入描述")
    print("第一行输入两个正整数 N,M,表示矩阵大小。")
    print("接下来 N 行 M 列表示矩阵内容。")
    // 矩阵 [行数, 列数]
    let NM = (readLine() ?? "").split(separator: " ").map { Int($0) ?? 0 }
    if NM.count != 2 {
        print("无")
        return
    }
    let N = NM[0], M = NM[1]
    // 矩阵
    var matrix = Array(repeating: Array(repeating: 0, count: M), count: N)
    for i in 0 ..< N {
        matrix[i] = (readLine() ?? "").split(separator: " ").map { Int($0) ?? 0 }
    }

    print("下一行包含一个正整数 K。")
    // 目标数组长度
    let K = Int(readLine() ?? "") ?? 0
    print("下一行包含 K 个整数,表示所需包含的数组,K 个整数可能存在重复数字。")
    print("所有输入数据小于1000。")
    // 目标数组
    let nums = (readLine() ?? "").split(separator: " ").map { Int($0) ?? 0 }

    // cnts[num] 记录的是 目标数组中num元素的个数
    var cnts = Array(repeating: 0, count: 1000)
    for num i

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

2024华为OD机试卷题 文章被收录于专栏

本专栏给大家提供了华为2024最新华为OD 题目汇总。华为OD机试刷题记录机考算法题库,帮助你上岸华为。提供C++/Java、JavaScript、Python四种语言的解法。

全部评论

相关推荐

点赞 1 评论
分享
牛客网
牛客企业服务