我正在尝试解决leetcode问题,在这里我想获得前k个频繁的数字。我正在尝试使用SortedSet解决O(log n)时间复杂性。
我的代码适用于所有输入 一项输入。
public class FreqNode
{
public int number;
public int freq;
public FreqNode(int n, int f)
{
number = n;
freq = f;
}
}
class Program
{
static void Main(string[] args)
{
int[] arr = new int[] { 3, 2, 3, 1, 2, 4, 5, 5, 6, 7, 7, 8, 2, 3, 1, 1, 1, 10, 11, 5, 6, 2, 4, 7, 8, 5, 6};
TopKFrequent(arr, 10);
Console.Read();
}
static void TopKFrequent(int[] nums, int k)
{
SortedSet<FreqNode> sl = new SortedSet<FreqNode>(new MyComparer());
Dictionary<int, FreqNode> ht = new Dictionary<int, FreqNode>();
foreach (int i in nums)
{
if (ht.ContainsKey(i))
{
sl.Remove(ht[i]);
ht[i].freq += 1;
}
else
{
ht[i] = new FreqNode(i, 1);
}
sl.Add(ht[i]);
}
for (int i = 0; i < k; i++)
{
FreqNode f = sl.ElementAt(i);
Console.WriteLine(f.number);
}
}
}
public class MyComparer : IComparer<FreqNode>
{
public int Compare(FreqNode fn1, FreqNode fn2)
{
//Remove entry with same number
//Retain entries with same frequencies.
if (fn1.number == fn2.number)
{
return 0;
}
else
{
int res = fn2.freq.CompareTo(fn1.freq);
if (res == 0)
{
return 1;
}
else
{
return res;
}
}
}
}
它将输出打印为-1,2,5,3,7, 6,6 ,4,8,10
代替-1,2,5,3,6,7,4,8,10,11
在调试过程中,我注意到比较器代码无法与现有的数字6进行比较。经过进一步调查,我发现SortedSet是使用Red-Black树实现的,但是我无法在代码中解决此错误。 / p>
答案 0 :(得分:0)
这个问题对我来说很有趣,因为我认为这可能是SortedSet错误,并让我逐步浏览了SortedSet源代码。 las,不是SortedSet错误...对不起,但是您的IComparer有点怪。
您的IComparer实现通过首先更改排序比较的条件,然后反转比较对象,然后更改返回值,确实使比较变得奇怪。
首先您的比较者在说,
如果“数量”属性相等,则节点相等(很好)
if (fn1.number == fn2.number)
{
return 0;
}
那是在说
在freq属性的倒数上排序(用fn1切换fn2可能不是一个好主意,并且排序标准已更改为'freq'属性(可能还可以))
int res = fn2.freq.CompareTo(fn1.freq);
然后将相等的频率更改为不相等
如果“频率”比较的结果相等,就假装它不相等(可能不是一个好主意)
if (res == 0)
{
return 1;
}
糟糕的SortedSet的根必须旋转!! (哈哈哈!我开了一个数据结构的笑话!让它“根”?“旋转”?)
最后,Remove算法将'6'作为正确的子代查找,因为您的IComparer告诉它应该在该位置,而'6'实际上是左子代,因此Remove算法将其遗漏。
>顺便说一句,请记住,SortedSet中的2个“ 6”节点和字典中的“ 6”节点实际上都是相同的FreqNode引用,因此如果您要同时更改所有这些引用,需要。
您可以查看(并下载).NET源here 然后按照说明here
将Visual Studio设置为调试源最后,如果您坚持要以这种方式解决top-k问题,请尝试使用此比较器:
public class MyComparer : IComparer<FreqNode>
{
public int Compare(FreqNode fn1, FreqNode fn2)
{
return fn1.number == fn2.number ? fn1.freq.CompareTo(fn2.freq) : fn1.number.CompareTo(fn2.number);
}
}
干杯,感谢您的调试!