LeetCode 820ワード圧縮符号化(接尾辞木)

1.トピック

単語のリストを考えると、このリストには、文字列SインデックスとインデックスリストAとしてエンコードされます

リストがある場合たとえば、["time", "me", "bell"]私たちは次のように表すことができるS = "time#bell#"indexes = [0, 2, 5]

各インデックスのために、我々はまでの文字列を読み込み開始位置にある文字列Sからインデックスすることができます"#"言葉の私達の前のリストを復元するために、エンド。

そして、エンコーディングのための与えられた単語リストを成功させるために、文字列の最小の長さはどのくらいですか?

示例:
输入: words = ["time", "me", "bell"]
输出: 10
说明: S = "time#bell#" , indexes = [0, 2, 5] 。
 
提示:
1 <= words.length <= 2000
1 <= words[i].length <= 7
每个单词都是小写字母 。

出典:滞在ボタン(LeetCode)
リンクします。https://leetcode-cn.com/problems/short-encoding-of-words
すべてのネットワークからの控除が著作権を保有。商業転載は、ソースを明記してください許可公式、非商用の転載をご連絡ください。

2.問題解決

2.1逆引き参照の文字列+文字

  • 各ストリングは従っ長さに降順で反転されます
  • 後で蓄積と「接尾辞」(反転後の接頭辞)に文字列の前に表示された単語を検索し、その後、解答文字列を結合する、または追加しないでください #和字符串
class Solution {
public:
    int minimumLengthEncoding(vector<string>& words) {
    	for(string& w : words)
    		reverse(w);//反转每个字符串
    	sort(words.begin(), words.end(),[&](string& a, string& b){
    		return a.size() > b.size();//长的在前
    	});
    	string ans;
    	for(string& w : words)
    	{
            size_t pos = ans.find(w);
            //在ans里查找,没找到,或者,找到了,但是不是反转后的前缀
    		if(pos == string::npos || ans[pos-1]!='#')
            // 注意["me" ,"mean"]之类的例子
    			ans += "#"+w;
    	}
    	return ans.size();
    }

    void reverse(string& s)
    {
    	int i = 0, j = s.size()-1;
    	while(i < j)
    		swap(s[i++],s[j--]);
    }
};

ここに画像を挿入説明

2.2接尾辞木

class Trie
{
public:
	unordered_map<char,Trie*> m;
	// bool isEnd = false;

	void rev_insert(string& s)
	{
		Trie* root = this;
		for(int i = s.size()-1; i >= 0; --i)
		{
			if(!(root->m).count(s[i]))
			{
				Trie* node = new Trie();
				root->m.insert(make_pair(s[i],node));
			}
			root = root->m[s[i]];
		}
		// root->isEnd = true;
	}
};
class Solution {
	int len = 0;
public:
    int minimumLengthEncoding(vector<string>& words) {
    	Trie *t = new Trie();
    	for(string& w : words)
    		t->rev_insert(w);
    	dfs(t,0);
    	return len;
    }

    void dfs(Trie * root, int count)
    {
    	if(root->m.size()==0)// 是叶子节点
    	{
    		len += count+1;// +1是 ‘#’
    		return;
    	}
    	for(auto it = root->m.begin(); it != root->m.end(); ++it)
    		dfs(it->second, count+1);
    }
};

ここに画像を挿入説明

公開された780元の記事 ウォンの賞賛1126 ビュー30万+

おすすめ

転載: blog.csdn.net/qq_21201267/article/details/105158592