华为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四种语言的解法。