leetcode—NO.692
C#解题思路
- 先遍历字符数组words,挑选出不同的字符,并在已遍历的记录中查找是否出现过,若出现过,则次数加1,若没有,则添加。很容易想象出,用两个循环遍历,第一个遍历words数组,搜一搜,第二个嵌套在里面,遍历已经遍历的字符串,给个名字mydic。
- 由1已得words之中有多少个不同的字符串,并且每一个字符串出现的频率。接下来根据频率排个序,有个坑,相同频率的字符串要根据字符串字母的顺序再排序。
力扣的题一般的for循环嵌套是通过不了的,一般解决方法是:利用key–value键值对查找的方法,可以将复杂度为**O(n2)**或者**O(n3)**降为O(1);另一种是滑动窗口,跟网络协议的滑动窗口协议差不多原理,但是前提是要适合使用条件,目前不太懂,只知道可能大范围里有个小范围可以用吧。
第一次
注释1:为了找到字符串数组的不同字符,使用了字典Dictionary类,利用key直接找出value的方法。为了提高查找效率。
注释2:字典类存放了不同字符串及其出现的次数,为了进行排序,多创建了一个list类。有想过编写一个list+dictionary的类(smile)写不出来。
public class Solution {
public IList<string> TopKFrequent(string[] words, int k) {
List<string> m_ilist = new List<string>();
// 1
var mydic = new Dictionary<string, int>();
// 2
List<KeyValuePair<string, int>>tolist=new List<KeyValuePair<string, int>>();
int i, value;
int length = words.Length;
for (i = 0; i < length; ++i)
{
if (!mydic.TryGetValue(words[i], out value))
mydic.Add(words[i], 1);
else
mydic[words[i]]=value+1;
}
foreach(var item in mydic)
{
tolist.Add(item);
}
tolist.Sort(delegate (KeyValuePair<string, int> x, KeyValuePair<string, int> y)
{
if (x.Value == y.Value)
return x.Key.CompareTo(y.Key);
else
return y.Value.CompareTo(x.Value);
});
if(k<=tolist.Count)
for (i = 0; i < k; ++i)
{
m_ilist.Add(tolist[i].Key);
}
return m_ilist;
}
}
第二次
去掉了if(k<=tolist.Count)判断条件,为了降低运行时间,然而没有用。甚至还久了一点。
第三次
这就神奇了,直接在列表List比较关于字典Dictionary的有关信息。牛
public class Solution {
public IList<string> TopKFrequent(string[] words, int k) {
var mydic = new Dictionary<string, int>();
List<string> m_ilist;
int i, value;
int length = words.Length;
for (i = 0; i < length; ++i)
{
if (!mydic.TryGetValue(words[i], out value))
mydic.Add(words[i], 1);
else
mydic[words[i]]=value+1;
}
m_ilist = mydic.Keys.ToList();
m_ilist.Sort(delegate (string x, string y)
{
if (mydic[x] == mydic[y])
return x.CompareTo(y);
else
return mydic[y].CompareTo(mydic[x]);
});
return m_ilist.GetRange(0, k);
}
}
第四次
看了官方题解,把*if···else··改成三元式····?····:····;*了
return mydic[x] == mydic[y] ? x.CompareTo(y) : mydic[y]-mydic[x] ;