C#:O(n²;)求大小为n和数为k的数组的n/k元素的解

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;

我正在尝试一个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; 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;
     }
}