排序后的数组中的多数元素介绍

87 阅读5分钟

在这篇文章中,我们将学习如何在一个排序的数组中找到多数元素。这包括使用线性搜索,二进制搜索和一个恒定时间算法。

内容

  1. 该问题的介绍
    • 输入
    • 输出
    • 输入和输出样本
    • 解决该问题的方法
  2. 方法1:线性搜索
    • 方法1的代码
    • 输出
    • 该方法的时间和空间复杂度
  3. 方法2:使用二进制搜索
    • 方法2的代码
    • 输出
    • 方法的时间和空间复杂度
  4. 方法3:O(1)时间
    • 方法3的代码
    • 输出
    • 该方法的时间和空间复杂度

问题简介

我们得到一个排序的数组,我们必须找到其中的多数元素。
让我们假设出现超过n/2次的元素是多数元素。

输入

我们的输入是:

  1. 分类的数组
  2. 数组的大小

输出

如果该元素在数组中存在,它将打印出多数元素
,如果不存在,则打印出不存在 。

输入和输出示例

输入数组:2 3 3 3 3 4
数组的大小:6

输出:多数元素存在于给定的数组中,它是3

输入数组。 6 22 22 22 34 45 56 78
阵列的大小:8

输出:多数元素不存在于给定数组中

输入数组。 8 9 9
阵列的大小:3

输出:它是给定数组中的多数元素

解决问题的方法

有很多方法来解决这个问题,其中两种方法与搜索类型相同。

它们是:

  1. 线性搜索
  2. 二进制搜索
  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的这篇文章中,我们讨论了解决在排序数组中寻找多数元素问题的三种方法。