static String target;
public static int minStickers(String[] stickers, String target) {
test.target=target;
int n=target.length();
Map<Character,Integer> chs=new HashMap<>();//记录target中的字母
for(int i=0;i<n;i++){
chs.put(target.charAt(i),chs.getOrDefault(target.charAt(i),0)+1);
}
int m=stickers.length;
Map<Character,Integer>[] l=new HashMap[m];//记录每张贴纸的有效字母
for (int i = 0; i <m ; i++) {
for (int j = 0; j <stickers[i].length() ; j++) {
char ch=stickers[i].charAt(j);
if(chs.containsKey(ch)){
if(l[i]==null) l[i]=new HashMap<>();
l[i].put(ch,l[i].getOrDefault(ch,0)+1);
}
}
}
int[] dp=new int[1<<n];//表示选择target中某些字母所需贴纸的最小数量
Arrays.fill(dp,-1);
dp[0]=0;//选择0个字母不需要贴纸
int ans=rcs(dp,chs,l,(1<<n)-1);
return ans==51?-1:ans;
}
static int rcs(int[] dp,Map<Character,Integer> chs, Map<Character,Integer>[] l,int mask){
if(dp[mask]>=0)
return dp[mask];
int min=51;//选择mask中的所有字母所需贴纸的最小数量
//选择某张贴纸
for(int i=0;i<l.length;i++){
int rest=mask;//表示剩下的字母
boolean flag=false;//贴纸是否包含剩余的字母
//从target中去掉贴纸包含的字母
if(l[i]!=null){
Map<Character,Integer> tmp=new HashMap<>(l[i]);//取出贴纸
//遍历target字母
for (int j = 0; j < target.length(); j++) {
if((rest&(1<<j))==0) continue;//判断是否为剩下的字母
char ch=target.charAt(j);
if(tmp.containsKey(ch)){
flag=true;
if(tmp.get(ch)==1) tmp.remove(ch);
else tmp.put(ch,tmp.get(ch)-1);
rest^= 1<<j;//去掉该字母
}
}
if(!flag) continue;//贴纸不包含剩下的字母则跳过
min=Math.min(min,rcs(dp,chs,l,rest)+1);//选中某张贴纸后,继续进入下一层选择贴纸
}
}
dp[mask]=min;
return dp[mask];
}
2022.5.14-----leetcode.691
最新推荐文章于 2022-06-24 15:52:23 发布