Word Abbreviation

这题实在算法说起来很简单,实现起来的细节难度却太大了,这里只列出一些需要考虑的地方

  • 一开始的原词长度小于等于3的话可以直接放进结果数组了
  • 你需要一个临时栈和一个临时哈希表,前者用于存放当前轮下还存在缩写冲突的原字符串和其下标,后者用于收集所有缩写以及对应下标
  • 你需要一个临时变量time来几轮这是第几轮缩写变换,因为题目要求是从字符串第二个字符开始进行缩写尝试,这个time变量可以辅助我们拿到当前词汇的缩写
  • 当缩写字符数仅为1时,缩写无意义了
  • 每一轮临时栈里面的数据都会被临时哈希表里面的逻辑过滤一遍,这样每次再返回临时栈里的数据规模就越来越小了

下面是根据上述逻辑细节实现的代码

class Solution(object):
    def wordsAbbreviation(self, dict):
        """
        :type dict: List[str]
        :rtype: List[str]
        """
        n = len(dict)
        res = [None] * n
        stack = []
        time = 0

        for i in xrange(n):
            if len(dict[i]) <= 3:
                res[i] = dict[i]
            else:
                stack.append([i, dict[i]])

        while stack:
            store = {}
            for index, word in stack:
                n = len(word)
                abbr = word[ : 1 + time] + str(n - 2 - time) + word[-1]
                if n - 2 - time <= 1:                    # 缩写字符长度只有1了,缩写无意义了
                    res[index] = word
                else:                                    # 缩写还有价值,继续进入哈希表
                    store.setdefault(abbr, [])
                    store[abbr].append(index)

            stack = []

            for abbr, index_lst in store.items():        
                n = len(index_lst)
                if n == 1:                               # 没有缩写冲突,可以放入res中了
                    res[index_lst[0]] = abbr
                else:
                    for i in xrange(n):                    # 还有冲突,则继续将原词和对应下标压入栈中
                        stack.append([index_lst[i], dict[index_lst[i]]])

            time += 1
        return res

这里不仅stack可以用来做遍历,用dict也是可以的

class Solution(object):
    def wordsAbbreviation(self, dict):
        """
        :type dict: List[str]
        :rtype: List[str]
        """
        n = len(dict)
        result = [0] * n
        store = collections.defaultdict(list)
        for index, word in enumerate(dict):
            store[word].append(index)

        offset = 1
        while store:
            newStore = collections.defaultdict(list)
            for word, indexList in store.iteritems():
                for index in indexList:
                    if len(dict[index]) - 2 <= offset:
                        result[index] = dict[index]
                    else:
                        newWord = dict[index][:offset] + \
                                str(len(dict[index]) - offset - 1) + \
                                dict[index][-1]
                        newStore[newWord].append(index)

            store.clear()
            for word, indexList in newStore.iteritems():
                if len(indexList) == 1:
                    result[indexList[0]] = word
                    continue
                store[word] += indexList
            offset += 1

        return result

results matching ""

    No results matching ""