820. LeetCode palabra de compresión de codificación (árbol de sufijos)

1. Tema

Dada una lista de palabras, esta lista se codifica como un índice de la cadena S y una lista de índice A.

Por ejemplo, si la lista es ["time", "me", "bell"], que puede expresarse como S = "time#bell#"y indexes = [0, 2, 5].

Para cada índice, que puede indexar de la cadena s en condiciones de comenzar a leer la cuerda hasta el "#"final, para restaurar nuestra lista previa de las palabras.

A continuación, la longitud mínima de la cadena para el éxito de una lista de palabras dada para la codificación es ¿cuánto?

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

Fuente: estancia botón (LeetCode)
enlace: https: //leetcode-cn.com/problems/short-encoding-of-words
propiedad de la deducción de todas las redes. reimpresión comercial póngase en contacto con la reimpresión autorizada oficial, no comercial por favor indique la fuente.

2. Resolución de Problemas

2.1 inversa cadena de caracteres +

  • Cada cadena se invierte en orden descendente de longitud conformidad
  • Encontrar una palabra que aparece más adelante en frente de la cadena a la acumulación y el "sufijo" (prefijo después de la inversión), entonces no unirse a la cadena de respuesta, o añadir #和字符串
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--]);
    }
};

Aquí Insertar imagen Descripción

2.2 árbol sufijo

  • Inserción de la cadena a la inversa árbol de prefijo (Trie)
  • Usando el hash memoria de tabla de sub-nodo, implementado como sigue
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);
    }
};

Aquí Insertar imagen Descripción

Publicados 780 artículos originales · ganado elogios 1126 · Vistas de 300.000 +

Supongo que te gusta

Origin blog.csdn.net/qq_21201267/article/details/105158592
Recomendado
Clasificación