宽度最小的子矩阵 (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