宽度最小的子矩阵 (100)
- 给定一个n行 * m列的矩阵;
- 给定一个k个整数的数组k_list;
- 在n*m的矩阵中找一个宽度最小的子矩阵,该子矩阵包含k_list中所有的整数;
 输入描述:
 第一行输入n,m 两个整数;
 后续n行每行输入 m个数据;
 输入k值;
 输入个整数
 输出描述:
 最小宽度值,若找不到,则输出-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 5
 1 2 2 3 1
 1 3 2 3 4
 3
 1 1 4
 输出:
 5
 思路:
- 滑动的子矩阵
- 从第一列起始,找一个宽度最小的子矩阵;
- 从第二列开始,找一个宽度最小的子矩阵;
- 依次到最后一列…
- 以上的宽度每次取最小值
 
class MinWidth:def solution(self, n, m, matrix, k_list):k_dict = self.to_dict(k_list)min_width = float("inf")# 类似双指针for start_idx in range(m):for end_idx in range(start_idx, m):temp_list = []# 获取当前子矩阵的所有元素for i in range(n):temp_list.extend(matrix[i][start_idx:end_idx+1])temp_dict = self.to_dict(temp_list)# 集合操作flag = Truefor key in k_dict:if key in temp_dict and k_dict[key] <= temp_dict[key]:continueelse:flag = Falsebreakif flag:min_width = min(min_width, end_idx - start_idx + 1)breakprint(min_width)def to_dict(self, alist):dict_ = {}for i in alist:dict_[i] = dict_.get(i, 0) + 1return dict_if __name__ == '__main__':min_width = MinWidth()while True:try:n, m = list(map(int, input().strip().split()))matrix = []for i in range(n):matrix.append(list(map(int, input().strip().split())))k = int(input().strip())k_list = list(map(int, input().strip().split()))min_width.solution(n, m, matrix, k_list)except KeyboardInterrupt:break