[LeetCode 639] Word Abbreviation

Given an array of n distinct non-empty strings, you need to generate minimalpossible abbreviations for every word following rules below.

  1. Begin with the first character and then the number of characters abbreviated, which followed by the last character.
  2. If there are any conflict, that is more than one words share the same abbreviation, a longer prefix is used instead of only the first character until making the map from word to abbreviation become unique. In other words, a final abbreviation cannot map to more than one original words.
  3. If the abbreviation doesn't make the word shorter, then keep it as original.

Example

Example 1:

Input:
["like","god","internal","me","internet","interval","intension","face","intrusion"]
Output:
["l2e","god","internal","me","i6t","interval","inte4n","f2e","intr4n"]

Example 2:

Input:
["where","there","is","beautiful","way"]
Output:
["w3e","t3e","is","b7l","way"]

Notice

  1. Both n and the length of each word will not exceed 400.
  2. The length of each word is greater than 1.
  3. The words consist of lowercase English letters only.
  4. The return answers should be in the same order as the original array.

 

分析

首先需要明确什么时候拥有相同压缩串的a和b如何区分。其实可以从前往后,依次增加prefix的长度然后直到压缩串不同为止。例如intension和intrusion,只有当prefix=inte和intr时,才能够进行区分。

那么首先我们先保存所有子串的最大压缩串,然后遍历所有的压缩子串,对于每一个压缩串i,在结果中寻找与其相同的压缩串,然后将坐标加入到set中,然后将set中所有的坐标对应的字符串均增加1位前缀,然后继续遍历结果中有没有跟压缩穿i 相同的压缩串,如果没有,就继续寻找下一个。

Code

class Solution {
public:
    /**
     * @param dict: an array of n distinct non-empty strings
     * @return: an array of minimal possible abbreviations for every word
     */
    vector<string> wordsAbbreviation(vector<string> &dict) {
        // write your code here
        vector<string> res;
        int len = dict.size();
        if (len == 0)
            return res;

        vector<int> pre(len, 1);
        for (int i = 0; i < len; i ++)
        {
            res.push_back(abbre(dict[i], pre[i]));
        }
        
        for (int i = 0; i < len; i ++)
        {
            
            while (true)
            {
                set<int> t;
                for (int j = i + 1; j < len; j ++)
                {
                    if (res[i] == res[j])
                    {
                        t.insert(i);
                        t.insert(j);
                    }
                }
                if (t.empty())
                    break;
                set<int>::iterator it;
                for (it = t.begin(); it != t.end(); it ++)
                {
                    res[*it] = abbre(dict[*it], ++pre[*it]);
                }
            }
        }

        return res;
    }
    
    string abbre(const string& s, int pre)
    {
        return pre >= s.size() -2 ? s: s.substr(0, pre) + to_string(s.size()-pre-1) +
            s.substr(s.size()-1);
    }
};

 

运行效率

Your submission beats 16.10% Submissions!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值