标签:led pytho while cpp entryset length rev Once sem
Given an array of n distinct non-empty strings, you need to generate minimal possible abbreviations for every word following rules below.
Example:
Input: ["like", "god", "internal", "me", "internet", "interval", "intension", "face", "intrusion"] Output: ["l2e","god","internal","me","i6t","interval","inte4n","f2e","intr4n"]
Note:
Java:
public List<String> wordsAbbreviation(List<String> dict) { int len=dict.size(); String[] ans=new String[len]; int[] prefix=new int[len]; for (int i=0;i<len;i++) { prefix[i]=1; ans[i]=makeAbbr(dict.get(i), 1); // make abbreviation for each string } for (int i=0;i<len;i++) { while (true) { HashSet<Integer> set=new HashSet<>(); for (int j=i+1;j<len;j++) { if (ans[j].equals(ans[i])) set.add(j); // check all strings with the same abbreviation } if (set.isEmpty()) break; set.add(i); for (int k: set) ans[k]=makeAbbr(dict.get(k), ++prefix[k]); // increase the prefix } } return Arrays.asList(ans); } private String makeAbbr(String s, int k) { if (k>=s.length()-2) return s; StringBuilder builder=new StringBuilder(); builder.append(s.substring(0, k)); builder.append(s.length()-1-k); builder.append(s.charAt(s.length()-1)); return builder.toString(); }
Java:
public List<String> wordsAbbreviation(List<String> dict) { String ans[] = new String[dict.size()]; abbreviate(ans, dict, IntStream.range(0, ans.length).boxed().collect(Collectors.toList()), 1); return Arrays.asList(ans); } private void abbreviate(String[] ans, List<String> dict, List<Integer> idxs, int k) { Map<String, List<Integer>> map = new HashMap<>(); idxs.stream().forEach(idx -> map.computeIfAbsent(getAbbr(dict.get(idx), k), key -> new ArrayList<>()).add(idx)); for (Entry<String, List<Integer>> entry : map.entrySet()) if (entry.getValue().size() == 1) ans[entry.getValue().get(0)] = entry.getKey(); else abbreviate(ans, dict, entry.getValue(), k + 1); } private String getAbbr(String s, int k) { return s.length() - k < 3 ? s : s.substring(0, k) + (s.length() - 1 - k) + s.charAt(s.length() - 1); }
Python:
class Solution(object): def wordsAbbreviation(self, dict): """ :type dict: List[str] :rtype: List[str] """ def isUnique(prefix, words): return sum(word.startswith(prefix) for word in words) == 1 def toAbbr(prefix, word): abbr = prefix + str(len(word) - 1 - len(prefix)) + word[-1] return abbr if len(abbr) < len(word) else word abbr_to_word = collections.defaultdict(set) word_to_abbr = {} for word in dict: prefix = word[:1] abbr_to_word[toAbbr(prefix, word)].add(word) for abbr, conflicts in abbr_to_word.iteritems(): if len(conflicts) > 1: for word in conflicts: for i in xrange(2, len(word)): prefix = word[:i] if isUnique(prefix, conflicts): word_to_abbr[word] = toAbbr(prefix, word) break else: word_to_abbr[conflicts.pop()] = abbr return [word_to_abbr[word] for word in dict]
Python:
class Solution(object): def abbr(self, word, size): if len(word) - size <= 3: return word return word[:size + 1] + str(len(word) - size - 2) + word[-1] def solve(self, dict, size): dlist = collections.defaultdict(list) for word in dict: dlist[self.abbr(word, size)].append(word) for abbr, wlist in dlist.iteritems(): if len(wlist) == 1: self.dmap[wlist[0]] = abbr else: self.solve(wlist, size + 1) def wordsAbbreviation(self, dict): """ :type dict: List[str] :rtype: List[str] """ self.dmap = {} self.solve(dict, 0) return map(self.dmap.get, dict)
C++:
/* Thought: Originally, used a hashset to store all existing pattern. If checked word exist in dict hashset, then return false. However, there is a case that: the word existed in the dict only for once, which is by accident the same as the checked work, then return true. Therefore, we need to keep track of what word has been catagrize into pattern. SO, use a HashMap<String, ArrayList> instead. Note: Dealing with char, integer, string. Be careful if char are turnning int integers. */ public class ValidWordAbbr { HashMap<String, ArrayList<String>> map; public ValidWordAbbr(String[] dict) { if (dict == null || dict.length == 0) { return; } map = new HashMap<String, ArrayList<String>>(); for (String s : dict) { String str = ""; if (s.length() <= 2) { str = s; } else { str += s.charAt(0) + (s.length() - 2 + "") + s.charAt(s.length() - 1); } if (!map.containsKey(str)) { ArrayList<String> list = new ArrayList<String>(); list.add(s); map.put(str, list); } else { if (!map.get(str).contains(s)) { map.get(str).add(s); } } } } public boolean isUnique(String word) { if (map == null || map.size() == 0) { return true; } String str = ""; if (word.length() <= 2) { str = word; } else { str += word.charAt(0) + (word.length() - 2 + "") + word.charAt(word.length() - 1); } if (map.containsKey(str) && map.get(str).size() == 1 && map.get(str).get(0).equals(word)) { return true; } return !map.containsKey(str); } } // Your ValidWordAbbr object will be instantiated and called as such: // ValidWordAbbr vwa = new ValidWordAbbr(dictionary); // vwa.isUnique("Word"); // vwa.isUnique("anotherWord");
C++:
class Solution { public: vector<string> wordsAbbreviation(vector<string>& dict) { int n = dict.size(); vector<string> res(n); vector<int> pre(n, 1); for (int i = 0; i < n; ++i) { res[i] = abbreviate(dict[i], pre[i]); } for (int i = 0; i < n; ++i) { while (true) { set<int> s; for (int j = i + 1; j < n; ++j) { if (res[j] == res[i]) s.insert(j); } if (s.empty()) break; s.insert(i); for (auto a : s) { res[a] = abbreviate(dict[a], ++pre[a]); } } } return res; } string abbreviate(string s, int k) { return (k >= s.size() - 2) ? s : s.substr(0, k) + to_string(s.size() - k - 1) + s.back(); } };
类似题目:
[LeetCode] 288.Unique Word Abbreviation 独特的单词缩写
320. Generalized Abbreviation
408.Valid Word Abbreviation
411. Minimum Unique Word Abbreviation
527. Word Abbreviation
[LeetCode] 527. Word Abbreviation 单词缩写
标签:led pytho while cpp entryset length rev Once sem
原文地址:https://www.cnblogs.com/lightwindy/p/9625356.html