在这篇文章中,我们将学习如何在一个排序的数组中找到多数元素。这包括使用线性搜索,二进制搜索和一个恒定时间算法。
内容
- 该问题的介绍
- 输入
- 输出
- 输入和输出样本
- 解决该问题的方法
- 方法1:线性搜索
- 方法1的代码
- 输出
- 该方法的时间和空间复杂度
- 方法2:使用二进制搜索
- 方法2的代码
- 输出
- 方法的时间和空间复杂度
- 方法3:O(1)时间
- 方法3的代码
- 输出
- 该方法的时间和空间复杂度
问题简介
我们得到一个排序的数组,我们必须找到其中的多数元素。
让我们假设出现超过n/2次的元素是多数元素。
输入
我们的输入是:
- 分类的数组
- 数组的大小
输出
如果该元素在数组中存在,它将打印出多数元素
,如果不存在,则打印出不存在 。
输入和输出示例
输入数组:2 3 3 3 3 4
数组的大小:6
输出:多数元素存在于给定的数组中,它是3
输入数组。 6 22 22 22 34 45 56 78
阵列的大小:8
输出:多数元素不存在于给定数组中
输入数组。 8 9 9
阵列的大小:3
输出:它是给定数组中的多数元素
解决问题的方法
有很多方法来解决这个问题,其中两种方法与搜索类型相同。
它们是:
- 线性搜索
- 二进制搜索
- 当给定的条件是多数元素存在于数组中。
方法1:线性搜索
我们将找到第n/2个元素并将其存储在值中,然后我们将使用线性搜索来找到数组中元素的数量,如果它大于n/2的底限值,那么它就是多数元素,否则就不存在多数元素。
让我们举一个例子,并追踪其步骤。
让数组为:
4 6 8 9 9
9 9
这里数组的大小是7 ,所以n/2是3
索引3的元素是9,我们把它储存在变量值中。
现在我们将对数组中的值进行线性搜索,如果找到就增加计数。
第一个元素是4, 计数为0。
第一个元素是6, 计数是0。
第一个元素是8,计数 是0。
第一个元素是9,计数 为1。
第一个元素是9,计数为 2 。
第一元素是9的计数是 3 。
第一元素是9的计数是 4。
因为count=4大于n/2=3,所以多数元素是9。
方法1的代码
# include <stdio.h>
# include <stdbool.h>
void main()
{
int arr[] ={4, 6, 8, 9, 9, 9, 9};
int n = 7;
int count=0;
int value;
int i;
int mid= n/2;
value=arr[mid];
for (i = 0; i < n; i++)
{
if (arr[i] == value)
count++;
}
if (count>mid)
{
printf("%d appears more than %d times in array,it is majority element",value, mid);
}
else
{
printf("No majority element present");
}
}
输出
9 appears more than 3 times in array,it is majority element.
...Program finished with exit code 0
Press ENTER to exit console.
现在是多数元素不存在的情况。
数组是4,6,8,8,9,9,9
这里的大小是7
n/2=3
在3处的元素是8。
通过线性搜索,8的计数是2,小于3。
输出
No majority element present
...Program finished with exit code 0
Press ENTER to exit console.
该方法的时间和空间复杂度
由于我们使用的是线性搜索,并且我们有一个索引从0到n变化的for循环,时间复杂度为O(n)。
由于没有使用辅助空间,空间复杂度为O(1)。
方法2:使用二进制搜索
我们将找到第n/2个元素并将其存储在变量中,我们将使用二进制搜索来找到该元素的计数,如果它的计数大于n/2,我们将打印它是多数元素,如果不是,则打印不存在多数元素。
让我们举一个例子,并追踪其步骤:
让数组为:
6 9 14 14 14 14 19
这里数组的大小是7 ,所以n/2是3
索引3的元素是14,我们把它存储在变量值中。
现在我们将对数组中的值进行二进制搜索,如果找到就增加计数。
mid=n/2=3
索引3的元素是14 , 计数是1。
现在我们将在数组的左边和右边都进行搜索
对于左边的子数组,结束索引=mid-1=2
新的mid是0+2/2=1
索引1的元素是9 ,计数是1。
对于右边的子阵列,开始指数=mid+1=4 新的中点是4+6/2=5
索引5的元素是14 , 计数是2。
所以对于右边的子数组,我们将向左和向右进行 。 对于左边,结束索引是5-1=4
,新的中间是4+4/2=4 , 索引4的元素是14
计数是3, 因为它只有一个元素,我们在这里停止。 对于右边,开始索引是5+1=6,
新的中间是6+6/2=6
索引6的元素是14 计数是4, 因为只有一个元素,我们在这里停止。
由于count=4大于n/2=3,多数元素是9。
方法2的代码
# include <stdio.h>
# include <stdbool.h>
int binSearch(int arr[], int low, int high, int x)
{
if (high >= low)
{
int mid = (low + high)/2; /*low + (high - low)/2;*/
if ( (mid == 0 || x > arr[mid-1]) && (arr[mid] == x) )
return mid;
else if (x > arr[mid])
return binSearch(arr, (mid + 1), high, x);
else
return binSearch(arr, low, (mid -1), x);
}
return -1;
}
bool isMaj(int arr[], int n, int x)
{
int i = binSearch(arr, 0, n-1, x);
if (i == -1)
return false;
if (((i + n/2) <= (n -1)) && arr[i + n/2] == x)
return true;
else
return false;
}
int main()
{
int arr[] = {6, 9, 14, 14, 14, 14, 19};
int n = 7;
int mid=n/2;
int x=arr[mid];
if (isMaj(arr, n, x))
printf("%d appears more than %d times in array.It is majority element",
x, n/2);
else
printf("no majority element is present");
return 0;
}
输出
14 appears more than 3 times in array.It is majority element
...Program finished with exit code 0
Press ENTER to exit console.
如果没有多数元素存在,那么:
数组是6, 9, 10, 10, 14, 14, 19
这里的大小是7
n/2=3 3
处的元素是10,
通过二进制搜索,10的计数是2,小于3,
因此没有多数元素存在。
输出
no majority element is present
...Program finished with exit code 0
Press ENTER to exit console.
该方法的时间和空间复杂度
由于我们使用的是二进制搜索,因此时间复杂度为O(log(n))。
由于没有使用辅助空间,空间复杂度为O(1)。
方法3:O(1)时间方法
我们假设最频繁的元素已经存在。因此,多数元素将总是出现在中间位置,因为其频率超过了元素总数的一半。
因此,我们必须采取第n/2个元素。
让我们看一个例子:
数组是12,12,67,67,67,67,90
大小为7
n/2=7/2=3
n/2处的元素是67,所以返回67作为多数元素。
方法3的代码
#include <stdio.h>
#include <stdbool.h>
int main()
{
int arr[] = { 12, 12, 67, 67, 67, 67, 90 };
int n = 7;
int mid =n/2;
int x=arr[mid];
printf("The majority element is %d",x);
}
输出
The majority element is 67
...Program finished with exit code 0
Press ENTER to exit console.
该方法的时间和空间复杂度
由于我们只取第n/2个元素,所以时间复杂度为O(1)。
由于没有使用辅助空间,空间复杂度为O(1)。
因此,在OpenGenus的这篇文章中,我们讨论了解决在排序数组中寻找多数元素问题的三种方法。