We are given N different types of stickers. Each sticker have a lowercase 中文版 word on it.
You would as-spell out the given target
string by cutting individual letters from your collection of stickers and rear Ranging them.
You can use each sticker more than once if you want, and you have infinite quantities of each sticker.
What is the minimum number of stickers so need to spell out the target
? If The task is impossible, return-1.
Example 1:
Input:
["with", "Example", "Science"], "Thehat"
Output:
3
Explanation:
We can use the 2 "with" stickers, and 1 "example" sticker. After cutting and rearrange the letters of those stickers, we can form the target "Thehat". Also, the minimum number of stickers necessary to form the target string.
Example 2:
Input:
["Notice", "possible"], "Basicbasic"
Output:
-1
Explanation:
We can ' t form the target "basicbasic" from cutting letters from the given stickers.
Analysis
At first glance should be a DP problem, but do not know how to model, or do more problems to accumulate experience it.
The first is to understand the meaning of the topic, from the description of the detour around to find out what the problem really requires. The input of this question is a set of strings, and a target string, for a given string can take its arbitrary portion of the partition, the same string can be used multiple times, so as to form the target string, the string from the input set of the minimum string tree to form a target string. Very tedious description, stripped under the useless information is actually given a string collection s, and a target string T. The minimum number of strings in S is used to satisfy the number of characters required by T.
Use the mapping of array subscripts to values to store the characters and their number in each sticker and target string, and use backtracking to traverse all possibilities.
See the next recursive traversal of the code, or not very understand, or to see the next DP solution. the method of DP plus backtracking recursion is used to traverse the solution of all possible. For each sticker, it is used to make up the target string, and part of it is left, so that it can be solved recursively.
Using a map to store the DP array, key is the target string to be composed, the value is the optimal solution, and the minimum number of sticker is used.
for string s (-1 if impossible). Note s is sorted.clearly, dp[""] = 0, and the problem asks for dp[target].
State transition equation:
dp[s] = min(1+dp[reduced_s]) for all stickers, here reduced_s is a new string after certain sticker applied
The above means that for s we loop from all stickers to form part of it, then the remainder of it will continue to be composed, which is the same problem. Recursive solution can, more say useless directly on the code to analyze:
classSolution { Public intminstickers (string[] stickers, String target) {intm =stickers.length; int[] MP =New int[M] [26]; Map<string, integer> DP =NewHashmap<>(); for(inti = 0; I < m; i++) for(CharC:stickers[i].tochararray ()) mp[i][c-' a ']++;//The m-row represents the M-sticker,0~25 column representing the letter a~z, which in effect arranges the characters in the string in order.Dp.put ("", 0); returnHelper (DP, MP, Target); }//The MP array stores the characters and their numbers for each sticker, and target is the destination string to be composed in the current recursive hierarchy Private intHelper (map<string, integer> DP,int[] MP, String target) { if(Dp.containskey (target))returnDp.get (target); intAns = integer.max_value, n =mp.length; int[] tar =New int[26]; for(CharC:target.tochararray ()) tar[c-' a ']++;//stores the characters and their number required to compose the target string//for each sticker attempt to use it as part of the target string, the recursive solution for(inti = 0; I < n; i++) { //The optimization here is interesting so that the entire loop starts with the sticker of the first character in the target string, which reduces the calculation if(Mp[i][target.charat (0)-' a '] = = 0)Continue; StringBuilder SB=NewStringBuilder ();//used to store the remaining target string, which is the part that participates in the next round of recursion//for the current sticker, match from A~z for(intj = 0; J < 26; J + +) {//if the target string requires a number of characters and there is a certain number of characters in the current sticker, subtract the required quantity from the quantity that is required, and the number of characters remaining, and continue to look for it in the next round recursion if(Tar[j] > 0 ) for(intk = 0; K < Math.max (0, tar[j]-mp[i][j]); k++) Sb.append (Char) (' a ' +j)); } String S=sb.tostring (); intTMP = Helper (DP, MP, s);//Pass the remaining component as the new target string to the lower iteration, because the sticker can be reused so the MP does not move if(tmp! =-1) ans = math.min (ans, 1+tmp); } dp.put (target, ans= = Integer.max_value? -1: ans); returnDp.get (target); }}
The above optimization is interesting, because if the target string can be spelled out by all stickers, then all sticker that contain the first character in Target will have at least one of the final results, then in turn think, We can start by stickers to traverse all possible times directly from the sticker containing the first character in the target string. This problem is still relatively difficult, first use map to store the DP array, followed by the use of dp+ recursive way to traverse.
LeetCode691. Stickers to Spell Word