题目为 给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
思路一开始为,遍历集合,对每个元素计算全排列的所有可能集合。
代码如下。很长(复杂度较高,执行超时,可以跳过,直接看第二个解法)
public IList<IList<string>> GroupAnagrams(string[] strs)
{
bool falgNull = false;
int nullCount = 0;
//结果集合
IList<IList<string>> liResAll = new List<IList<string>>();
if (strs==null||strs.Length==0)
{
return liResAll;
}
//存储strs的所有元素 值存储的是元素位置
Dictionary<string, int> dicAll = new Dictionary<string, int>();
for (int i = 0; i < strs.Length; i++)
{
if (string.IsNullOrEmpty(strs[i]))
{
nullCount++;
falgNull = true;
continue;
}
if (!dicAll.ContainsKey(strs[i]))
{
dicAll.Add(strs[i], 1);
}
else
{
dicAll[strs[i]] += 1;
}
}
for (int i = 0; i < strs.Length; i++)
{
if (string.IsNullOrEmpty(strs[i]))
{
continue;
}
if (dicAll[strs[i]] <= 0)
{
continue;
}
List<string> liTemp = GetAllDetail(strs[i]);
List<string> liTempTrue = new List<string>();
foreach (string item in liTemp)
{
while (dicAll.ContainsKey(item)&&dicAll[item]>0)
{
liTempTrue.Add(item);
dicAll[item] -= 1;
}
//dicAll.Remove(item);
}
if (liTempTrue.Count>0)
{
liResAll.Add(liTempTrue);
}
}
if (falgNull)
{
List<string> liNull= new List<string>();
for (int i = 0; i < nullCount; i++)
{
liNull.Add("");
}
liResAll.Add(liNull);
}
return liResAll;
}
//查找全排列
public List<string> GetAllDetail(string str)
{
List<Char> li = str.ToList();
GetAllAKANB(new StringBuilder(),str);
return resAllLi;
}
List<string> resAllLi = new List<string>();
Dictionary<int, int> dicALLli = new Dictionary<int, int>();
public void GetAllAKANB(StringBuilder sb,string str)
{
if (sb.Length==str.Length)
{
resAllLi.Add(sb.ToString());
}
for (int i = 0; i < str.Length; i++)
{
if (dicALLli.ContainsKey(i))
{
continue;
}
dicALLli.Add(i, 0);
sb.Append(str[i]);
GetAllAKANB(sb,str);
sb.Remove(sb.Length - 1,1);
dicALLli.Remove(i);
}
}
第二种解法,对数组排序,例如abc、cba、bac排序后都是abc。根据这个计算。代码如下
public IList<IList<string>> GroupAnagrams(string[] strs)
{
var res = new List<IList<string>>();
var grp = new Dictionary<string, IList<string>>();
// 遍历每一个字符串
foreach (var str in strs)
{
// Concat:将指定字符串连接到此字符串的结尾
// OrderBy 将char升序排列
// rt是排序过的字母 eat -> aet
string rt = String.Concat(str.OrderBy(ch => ch));
// 放入字典中
if (grp.ContainsKey(rt))
{
grp[rt].Add(str);
}
else
{
grp[rt] = new List<string> { str };
}
}
foreach (var key in grp.Keys)
{
res.Add(grp[key]);
}
return res;
}