核心思路
用Hashmap保存滑动窗口内的元素和频次。然后检查滑动窗口内的元素是否覆盖了带匹配数组的元素。是则返回当前的窗口长度。
算法设计流程
滑动窗口实现:双层for循环,外层for循环代表窗口后沿,内层for循环代表窗口前沿,窗口前沿每向右移动一个位置,将当前位置的元素加入滑动窗口中(用hashmap统计),并做判断,当前窗口内元素是否覆盖了数组中的元素,若是则更新最小长度,退出内层for循环,重新初始化窗口,窗口后沿右移。
代码细节
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
public class Main {
public static int ans=Integer.MAX_VALUE;
public static boolean cover(HashMap<Integer,Integer> nums,HashMap<Integer,Integer> win){
for (int v :
nums.keySet()) {
if (nums.get(v)>win.getOrDefault(v,0)){
return false;
}
}
return true;
}
public static void bp(HashMap<Integer,Integer> nums,int n,int m,int[][] map){
for (int i = 0; i < m; i++) {
HashMap<Integer,Integer> win=new HashMap<>();
for (int j = i; j < m; j++) {
for (int k = 0; k < n; k++) {
win.put(map[k][j],win.getOrDefault(map[k][j],0)+1);
}
if (cover(nums,win)){
ans=Math.min(ans,j-i+1);
break;
}
}
}
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String[] str1=scanner.nextLine().split(" ");
int n=Integer.parseInt(str1[0]);
int m=Integer.parseInt(str1[1]);
int[][] map=new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
map[i][j]= scanner.nextInt();
}
}
scanner.nextLine();
int k= scanner.nextInt();
scanner.nextLine();
HashMap<Integer,Integer> nums=new HashMap<>();
int[] temp=new int[k];
for (int i = 0; i < k; i++) {
temp[i]= scanner.nextInt();
}
for (int i = 0; i < k; i++) {
nums.put(temp[i], nums.getOrDefault(temp[i],0)+1);
}
// Iterator iterator=nums.entrySet().iterator();
// while (iterator.hasNext()){
// System.out.println(iterator.next());
// }
bp(nums,n,m,map);
System.out.println(ans);
}
}