단어리스트로부터,이리스트는 문자열 S 인덱스와 인덱스리스트 A.로 인코딩 될
예를 들어,리스트가있는 경우 [ "시간", "나" , "종", 우리는 S = "# 시간 벨 #"과 인덱스 = 0, 2, 5와 같이 표현 될 수있다 ].
각 인덱스를 들어, 우리는 단어의 이전 목록을 복원하려면 "#"이 끝날 때까지 위치에있는 문자열 S에서 문자열 인덱스를 읽어 시작할 수 있습니다.
그런 다음 인코딩 주어진 단어 목록의 성공에 문자열의 최소 길이는 얼마입니까?
예 1 :
입력 : 단어 = "시간", "나", "종"]
출력 : 10
설명 : S = "# 시간 벨 # ", 인덱스 = 0, 2, 5].
개인의 생각은 : 첫째, 만 두 단어 가정 문제를 이해하기에, B는 그 때 A, B 또는 A 접미사의 접미사 B는 문제가 너무 분명 여부를 확인해야 할 것이다, 우리가 서로를 때마다 결정하는 A 또는 B 여부 우리는 단어의 끝을 정렬 판사을 보장 할 수 있도록 자사의 접미사,가, 생각할 수있는 일종의 분명히 불편, 그것은 첫 번째 단어 반전, 다음 분류 간주 될 수 있습니다.
예를 들어, 우선, 워드 그룹
string[] words = { "outint", "like", "int", "dislike", "nt" };
역으로 첫 번째 단어를
다음과 정렬 단어 그룹 - 긍정적 순서
단어는 종류를 설정 - 역순으로
정렬 한 후, 같은 값 (접두사) 훨씬 더 편리, 한 라인에 패리티 인접한 값, 여기서주의에 관해서는 긍정적 인 순서 정렬을 사용하는 경우이다 찾고 전면 후면에서 통과하기 위해 필요한 비교 ([4]=>[3]=>...=>[0])
역에 뒤로, 앞 ([0]=>[1]=>...=>[4])
이유도 위의 그림 참조 이해를 위해.
씨#
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;
}
}
요구의 다른 세트를 시간