C#:O(n²;)求大小为n和数为k的数组的n/k元素的解
我正在尝试一个O(n²)解决方案,以找到在给定数组中哪些元素出现的次数超过n/k次(在本例中,n=8,超过两次)。我相信我已经找到了解决方案,但我似乎不明白为什么输出(如下所示)不是[2,3]。我知道出现的是索引I=3处的元素2,但我认为C#:O(n²;)求大小为n和数为k的数组的n/k元素的解,c#,arrays,C#,Arrays,我正在尝试一个O(n²)解决方案,以找到在给定数组中哪些元素出现的次数超过n/k次(在本例中,n=8,超过两次)。我相信我已经找到了解决方案,但我似乎不明白为什么输出(如下所示)不是[2,3]。我知道出现的是索引I=3处的元素2,但我认为if(count>(arr.Length/k))条件会解决这个问题 int[] arr = { 3, 1, 2, 2, 1, 2, 3, 3 }; int k = 4, count = 1; for(int i = 0; i < arr.Length;
if(count>(arr.Length/k))
条件会解决这个问题
int[] arr = { 3, 1, 2, 2, 1, 2, 3, 3 };
int k = 4, count = 1;
for(int i = 0; i < arr.Length; i++)
{
for (int j = i + 1; j < arr.Length; j++)
{
if (arr[i] == arr[j])
{
count++;
if (count > (arr.Length / k))
{
Console.WriteLine(arr[i] + " " + i);
count = 1;
}
}
}
}
问题是,只有当存在匹配且
计数
大于arr.Length/k时,才重置计数
。您需要在内部for
循环结束时重置它,或者最好在内部for
循环之前定义它,因为在该循环之外不需要它。另外,我猜只要计数符合你的条件,你就会想打破这个循环,或者你会继续写同样的东西
int[] arr = { 3, 1, 2, 2, 1, 2, 3, 3 };
int k = 4;
for(int i = 0; i < arr.Length; i++)
{
int count = 1;
for (int j = i + 1; j < arr.Length; j++)
{
if (arr[i] == arr[j])
{
count++;
if (count > (arr.Length / k))
{
Console.WriteLine(arr[i] + " " + i );
break;
}
}
}
}
或者,如果您更喜欢使用for
循环而不是Linq,那么您所需要的只是一个HashSet
来跟踪您已经看到的值
int[] arr = { 3, 1, 2, 2, 1, 2, 3, 3 };
int k = 4;
HashSet<int> seen = new HashSet<int>();
for(int i = 0; i < arr.Length; i++)
{
if(!seen.Add(arr[i]))
{
continue;
}
int count = 1;
for (int j = i + 1; j < arr.Length; j++)
{
if (arr[i] == arr[j])
{
count++;
if (count > (arr.Length / k))
{
Console.WriteLine(arr[i] + " " + i );
break;
}
}
}
}
int[]arr={3,1,2,2,1,2,3};
int k=4;
HashSet seen=新的HashSet();
对于(int i=0;i(arr.Length/k))
{
控制台写入线(arr[i]+“”+i);
打破
}
}
}
}
请注意,当值已在哈希集中时,Add
返回false。这不是最优化的方法吗?因为您不想检查最后一个arr.Length/k
元素,因为如果所有元素都相同,那么它们在数量上只能是are.Length/k
,而不是>are.Length/k
int[] arr = { 3, 1, 2, 2, 1, 2, 3, 3 };
int k = 4;
int target = arr.Length/k;
for(int i = 0; i < arr.Length - target; i++)
{
int count = 1;
for (int j = i + 1; j < arr.Length; j++)
{
if (arr[i] == arr[j])
{
count++;
if (count > (target))
{
Console.WriteLine(arr[i] + " " + i );
break;
}
}
}
}
您没有在正确的位置重置计数。它应该在内部<代码>之后重置为循环,而不是在<代码> > 语句中。作为优化,考虑仅计算代码< > AR.List/K < /C> >(即分配给循环外的变量)。另外,考虑代码< > AR.Stime< /C> > 9,而<代码> k>代码> <代码> 4 < /代码>。您希望arr.Length/k
返回什么结果(这就是您得到的结果)?
int[] arr = { 3, 1, 2, 2, 1, 2, 3, 3 };
int k = 4;
HashSet<int> seen = new HashSet<int>();
for(int i = 0; i < arr.Length; i++)
{
if(!seen.Add(arr[i]))
{
continue;
}
int count = 1;
for (int j = i + 1; j < arr.Length; j++)
{
if (arr[i] == arr[j])
{
count++;
if (count > (arr.Length / k))
{
Console.WriteLine(arr[i] + " " + i );
break;
}
}
}
}
int[] arr = { 3, 1, 2, 2, 1, 2, 3, 3 };
int k = 4;
int target = arr.Length/k;
for(int i = 0; i < arr.Length - target; i++)
{
int count = 1;
for (int j = i + 1; j < arr.Length; j++)
{
if (arr[i] == arr[j])
{
count++;
if (count > (target))
{
Console.WriteLine(arr[i] + " " + i );
break;
}
}
}
}
int[] arr = { 3, 1, 2, 2, 1, 2, 3, 3 };
int[] sorted = Sort(arr); //sort method
int k = 4;
int target = arr.Length/k;
int count = 0;
for(int i = 0; i < arr.Length - target; i++)
{
count++;
if(arr[i] != arr[i+1])
{
if(count > target)
Console.WriteLine($"{arr[i]} {count}");
count = 0;
}
}