这道题就是320和408两个题目合在一起:
- https://leetcode.com/problems/valid-word-abbreviation/description/
- https://leetcode.com/problems/generalized-abbreviation/description/
唯一需要注意的是,需要返回最短的长度,而最短的长度中数字只算一个长度,例如 the abbreviation "a32bc" has length = 4, 因为“32”长度算1.
因此定义一个class node, 不仅存放abbreviation 也存放 定义的“长度”,并且在dfs 中容易算出这个长度, 比如dfs 中 遇到 "10" 只需要长度 +1 即可。
code 长的有点恶心了,就是把 320 和 408 的code 合并在了一起而已。
class Solution { public String minAbbreviation(String target, String[] dictionary) { //"usaandchinaarefriends" [] 过这个case if(dictionary == null || dictionary.length ==0) return target.length()+""; List<String> dic = new ArrayList<>(); for(String str: dictionary){ //去掉字典里和 target 里长度不同的单词 if(str.length() == target.length()){ dic.add(str); } } List<Node> result = new ArrayList<>(); dfs(new StringBuilder(), result, target,0,0); Collections.sort(result,(o1,o2)->o1.len-o2.len); //int min_len = Integer.MAX_VALUE; //String min_str = ""; for(Node node: result){ boolean flag = false; for(String word: dic) { //System.out.println(node.abbr); flag = validWordAbbreviation(word,node.abbr); if(flag) break; } if(!flag){ return node.abbr; } } return ""; } private void dfs(StringBuilder curResult,List<Node> result, String word, int cur_index,int abbr_len){ if(curResult.length() == word.length() || cur_index == word.length()){ result.add(new Node(curResult.toString(), abbr_len)); return; } int len = curResult.length(); // 每次记录长度 //put the 剩下的可能的长度 for(int i=1; i<=word.length()-cur_index; i++){ // wrd: cur_index = 0, len =3, 可以放 1,2,3 // 当前result 里 最后一个字符得是字母才能 放数字 if(curResult.length()==0 || Character.isLetter(curResult.charAt(curResult.length()-1)) ){ curResult.append(i); dfs(curResult,result,word,cur_index+i,abbr_len+1); curResult.setLength(len); //恢复之前的长度 } } // put cur letter curResult.append(word.charAt(cur_index)); dfs(curResult,result, word,cur_index+1,abbr_len+1); curResult.setLength(len); } private boolean validWordAbbreviation(String word, String abbr) { int index = 0; String count = "0"; for(int i=0; i<abbr.length(); i++){ char c = abbr.charAt(i); if(Character.isLetter(c) ) { index = index + Integer.valueOf(count); if(index >= word.length() || c != word.charAt(index) ) return false; count = "0"; index++; } else { if(count.equals("0") && c=='0') return false; count += c; } } return index + Integer.valueOf(count) == word.length(); } } class Node{ String abbr; int len ; Node(String abbr, int len){ this.abbr = abbr; this.len = len; } }