leetcode288 - Unique Word Abbreviation - medium

An abbreviation of a word follows the form <first letter><number><last letter>. Below are some examples of word abbreviations:
a) it --> it (no abbreviation)
b) d|o|g --> d1g
c) i|nternationalizatio|n --> i18n
d) l|ocalizatio|n --> l10n
Assume you have a dictionary and given a word, find whether its abbreviation is unique in the dictionary. A word's abbreviation is unique if no other word from the dictionary has the same abbreviation.
Example:
Given dictionary = [ "deer", "door", "cake", "card" ]
isUnique("dear") -> false
isUnique("cart") -> true
isUnique("cane") -> false
isUnique("make") -> true

 

理解题意:本题有陷阱。它对unique的定义是no other word from the dictionary has the same abbreviation. 这个other说的很巧妙,真实unique不单单指新来word的abbr以前完全没出现过的case,还指abbr以前出现过,但造成以前abbr的单词和你今天刚传入的单词是一样的。这样的确还是no other word给出同一个abbr。
举例:
[cake cake jasmine]. << jack. j2k没出现过,ok
[cake cake jasmine]. << cake. c2e出现过,但也是cake造成的,ok
[cake cane jasmine]. << cake. c2e出现过,而且有一个c2e是由other words(cane)产生的,no.

最后问题等价转化:如果用两个map,存储对原始字符串的频率统计,以及缩写字符串的频率统计。那么一个word unique等同于word在两个map里取到的频次是一样的。(即要么没出现过取到都是0,要么所有取到的abbr的统计都来源于dict里这个单词的统计数)

细节:
1.这题unique函数里直接写return abbrs.get(abbr(word)) == dicts.get(word);不会有问题,不需要用getOrDefault。虽然==只对null和对象的比较有定义,基础变量类型不能和null相比。比如Integer a = 1; a == null不报错,但1 == null报错。但是本题根据Map<*, Integer>的范型定义,返回的是Integer是包装过的int是对象类型的,所以就算只有其中一个是返回null,另一个非null,比较不会报编译错误。
2.产生abbr的时候拼接第一个char+长度int+最后一个char,记得要转其中一个为String,否则加一加还是一堆数字。

 

实现:

class ValidWordAbbr {

        private Map<String, Integer> abbrs = new HashMap<>();
        private Map<String, Integer> dicts = new HashMap<>();

        public ValidWordAbbr(String[] dictionary) {
            for (String s : dictionary) {
                abbrs.put(abbr(s), abbrs.getOrDefault(abbr(s), 0) + 1);
                dicts.put(s, dicts.getOrDefault(s, 0) + 1);
            }
        }

        public boolean isUnique(String word) {
            return abbrs.get(abbr(word)) == dicts.get(word);
        }

        private String abbr(String s) {
            if (s.length() <= 2) {
                return s;
            } else {
                // P1: 中间做一下类型转换,否则会出现char+int+char还是数字的情况。
                return s.charAt(0) + String.valueOf(s.length() - 2) + s.charAt(s.length() - 1);
            }
        }
    }

    /**
     * Your ValidWordAbbr object will be instantiated and called as such:
     * ValidWordAbbr obj = new ValidWordAbbr(dictionary);
     * boolean param_1 = obj.isUnique(word);
     */

 

posted @ 2018-09-12 07:52  jasminemzy  阅读(192)  评论(0编辑  收藏  举报