単語のリストを考えると、このリストには、文字列SインデックスとインデックスリストAとしてエンコードされます
例えば、リストが[ "時間"、 "私" 、 "ベル"]、 我々は、S = "タイム#ベル#"とインデックス= [0、2、5のように表すことができます ]。
各インデックスのために、私たちは言葉の私達の前のリストを復元するには、「#」終了までの位置にある文字列Sから文字列のインデックスを読むことによって開始することができます。
そして、エンコーディングのための与えられた単語リストを成功させるために、文字列の最小の長さはどのくらいですか?
例1:
入力:言葉= [ "時間"、 "私"、 "ベル"]
出力:10
説明:S = "時間#ベル# "、インデックス= [0、2、5]。
個人の思考:まず、問題を理解する、2つだけの単語A、B、その後、彼らはA、Bまたは接尾語の接尾辞Bが困ってとても明らかであるかどうか、私たちはお互いを持っているすべての時間はAかBかどうかを判断するためにチェックしなければならないと仮定その接尾辞は、私たちは言葉の終わりをソートするために裁判官を保証することができますので、それは、考えられる一種である、それはソート、その後、第1ワード反転考えることができ、明らかに不便です。
例えば、第一、単語群
string[] words = { "outint", "like", "int", "dislike", "nt" };
まず、逆に単語
、その後、ソートグループの単語-正シーケンス
語のソートを設定-逆の順序で
長いライン上でパリティ隣接する値などとして、はるかに便利同じ値(プリフィックス)を探して、ソートした後、ここで注意することは、あなたがソート正シーケンスを使用している場合ということですフロントに戻ってからトラバースに必要な比較([4]=>[3]=>...=>[0])
、逆にバックにフロントを([0]=>[1]=>...=>[4])
、理由のためだけでなく、上の図を参照してください理解していました。
C#の
class Program
{
static void Main(string[] args)
{
string[] words = { "outint", "like", "int", "dislike", "nt" };
Console.WriteLine(MinimumLengthEncoding(words));
Console.Read();
}
public static int MinimumLengthEncoding(string[] words)
{
/*首先要理解题意,假设只有两个词A,B
* 那么就要检查A是否是B的后缀,或者B是A的后缀,
* 这样显然麻烦,我们每次都要互相判断A或B是否是其的后缀,
* 可以想到排序,这样就能保证判断一次,
* 以单词的末尾进行排序显然是不方便的,所以可以考虑先将单词反转,然后进行排序
*/
//1.使用HashSet<>和SortedSet<>容器时间会明显变长,因为每次加入新元素都要排序去重,
//所以这里使用List<>
List<string> wordList = new List<string>();
//2-1.遍历所有单词,将其反转
foreach (string word in words)
{
//添加到List中
wordList.Add(new string(word.Reverse().ToArray()));
}
//2-2去重,倒序
//倒序,保证相同前缀的单词长的在前面
wordList = wordList.Distinct().OrderByDescending(reWord => reWord).ToList();
//3.首位作为初始值
string curStr = wordList.First(); //初始索引字符串
int count = curStr.Length; //初始索引字符串长度
//4.遍历单词集
for (int i = 0; i < wordList.Count - 1; i++)
{
//加上每次比较后的结果,ref保证当前索引字符串更新
count += CompareWords(ref curStr, wordList.ElementAt(i + 1));
}
//5.加上最后一个#
return ++count;
}
/// <summary>
/// 比较是否是前缀
/// </summary>
/// <param name="curStr">当前索引字符串</param>
/// <param name="nextWord">下一个准备比较单词</param>
/// <returns></returns>
private static int CompareWords(ref string curStr, string nextWord)
{
int cnt = 0;
//4-1.找出两个词中较短的数值
int min = Math.Min(curStr.Length, nextWord.Length);
//4-2.从后向前检查,
//因为判断是否前缀,所以最后不同就不是前缀了,前面的就不用判断了
for (int i = min - 1; i >= 0; i--)
{
//i==0即直到最后一个也符合,即next是cur的前缀
if (curStr[i] == nextWord[i] && i == 0)
{
cnt = 0;
}
//不同,即不是前缀,直接跳出
else if (curStr[i] != nextWord[i])
{
curStr = nextWord + curStr;
cnt = nextWord.Length + 1;//有一个#
break;
}
}
//4-3.最后返回本次计算后需要的长度
return cnt;
}
}
時間のニーズの異なるセット