📌  相关文章
📜  查找出现次数超过 ⌊N/3⌋ 次的所有数组元素

📅  最后修改于: 2021-09-16 10:59:54             🧑  作者: Mango

给定一个由N 个整数组成的数组arr[] ,任务是找到出现次数超过 floor (n/3) 次的所有数组元素。

例子:

方法一:

方法:基本的解决方案是有两个循环并跟踪所有不同元素的最大计数。如果最大计数大于 n/3,则打印它。如果遍历数组后最大计数不超过 n/3,则多数元素不存在。

C++
// C++ program to find Majority
// element in an array
#include 
using namespace std;
  
// Function to find Majority element
// in an array
void findMajority(int arr[], int n) {
     
    int flag = 0;
    for (int i = 0; i < n; i++) {
        int count = 0;
        for (int j = i; j < n; j++) {
            if (arr[i] == arr[j]) {
                count++;
            }
        }
        if (count > (n / 3)) {
            cout << arr[i] << " ";
            flag = 1;
        }
    }
    if (!flag)
        cout << "No Majority Element" << endl;
}
int main() {
 
    int arr[] = { 2, 2, 3, 1, 3, 2, 1, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    // Function calling
    findMajority(arr, n);
    return 0;
}
 
// This code is contributed by Aman Chowdhury


Java
// Java program to find Majority
// element in an array
  
import java.io.*;
  
class GFG {
  
    // Function to find Majority element
    // in an array
      static void findMajority(int arr[], int n)
    {
        int flag=0;
        for (int i = 0; i < n; i++) {
            int count = 0;
            for (int j = i; j < n; j++) {
                if (arr[i] == arr[j])
                    count++;
            }
  
            // if count is greater than n/3 means
              // current element is majority element
            if (count > n/3) {
                System.out.print(arr[i]+" ");
                  flag=1;
            }
        }
  
        // if flag is 0 means there is no
          // majority element is present
        if (flag==0)
            System.out.println("No Majority Element");
   
    }
  
    public static void main (String[] args) {
        int arr[] = { 2, 2, 3, 1, 3, 2, 1, 1 };
        int n = arr.length;
  
        // Function calling
        findMajority(arr, n);
    }
}
 
// This code is contributed by Aman Chowdhury


Javascript


C++
/* C++ program for finding out majority
element in an array */
#include 
using namespace std;
  
void findMajority(int arr[], int size)
{
    unordered_map m;
    for(int i = 0; i < size; i++)
        m[arr[i]]++;
    int flag = 0;
    for(auto i : m)
    {
        if(i.second > size / 3)
        {
            flag =1;
            cout << i.first << " ";
        }
    }
    if(flag == 0)
        cout << "No Majority element" << endl;
}
  
// Driver code
int main()
{
    int arr[] = { 2, 2, 3, 1, 3, 2, 1, 1};
    int n = sizeof(arr) / sizeof(arr[0]);
      
    // Function calling
    findMajority(arr, n);
  
    return 0;
}
 
// This code is contributed by Aman Chowdhury


Java
import java.util.HashMap;
 
/* Program for finding out majority element in an array */
 
class MajorityElement
{
    private static void findMajority(int[] arr)
    {
        HashMap map = new HashMap();
        int flag=0;
        for(int i = 0; i < arr.length; i++) {
            if (map.containsKey(arr[i])) {
                    int count = map.get(arr[i]) +1;
                    if (count > arr.length /3) {
                        System.out.print(arr[i]+" ");
                          flag=1;
                    } else
                        map.put(arr[i], count);
 
            }
            else
                map.put(arr[i],1);
            }
              if(flag==0)
                System.out.println(" No Majority element");
    }
 
 
    /* Driver program to test the above functions */
    public static void main(String[] args)
    {
        int a[] = new int[]{2, 2, 3, 1, 3, 2, 1, 1};
         
        findMajority(a);
    }
}
 
// This code is contributed by Aman Chowdhury


C++
// C++ program to find Majority
// element in an array
#include 
using namespace std;
  
// Function to find Majority element
// in an array
void findMajority(int arr[], int n){
      int count1 = 0, count2 = 0;
    int first=INT_MAX, second=INT_MAX;
    int flag=0;
    for (int i = 0; i < n; i++) {
  
        // if this element is previously seen,
        // increment count1.
        if (first == arr[i])
            count1++;
  
        // if this element is previously seen,
        // increment count2.
        else if (second == arr[i])
            count2++;
      
        else if (count1 == 0) {
            count1++;
            first = arr[i];
        }
  
        else if (count2 == 0) {
            count2++;
            second = arr[i];
        }
  
        // if current element is different from
        // both the previously seen variables,
        // decrement both the counts.
        else {
            count1--;
            count2--;
        }
    }
  
    count1 = 0;
    count2 = 0;
  
    // Again traverse the array and find the
    // actual counts.
    for (int i = 0; i < n; i++) {
        if (arr[i] == first)
            count1++;
  
        else if (arr[i] == second)
            count2++;
    }
      
    if (count1 > n / 3){
        cout << first << " ";
          flag=1;
    }
    if (count2 > n / 3){
        cout << second << " ";
          flag=1;
    }
      if(flag==0){
          cout << "No Majority Element" << endl;
    }
}
   
int main() {
 
    int arr[] = { 2, 2, 3, 1, 3, 2, 1, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    // Function calling
    findMajority(arr, n);
  
    return 0;
}
 
// This code is contributed by Aman Chowdhury


Java
// Java program to find if any element appears
// more than n/3.
class GFG {
     
    static void findMajority(int arr[], int n)
    {
        int count1 = 0, count2 = 0;
        int flag=0;
        // take the integers as the maximum
        // value of integer hoping the integer
        // would not be present in the array
        int first = Integer.MIN_VALUE;;
        int second = Integer.MAX_VALUE;
     
        for (int i = 0; i < n; i++) {
     
            // if this element is previously
            // seen, increment count1.
            if (first == arr[i])
                count1++;
     
            // if this element is previously
            // seen, increment count2.
            else if (second == arr[i])
                count2++;
         
            else if (count1 == 0) {
                count1++;
                first = arr[i];
            }
     
            else if (count2 == 0) {
                count2++;
                second = arr[i];
            }
     
            // if current element is different
            // from both the previously seen
            // variables, decrement both the
            // counts.
            else {
                count1--;
                count2--;
            }
        }
     
        count1 = 0;
        count2 = 0;
     
        // Again traverse the array and
        // find the actual counts.
        for (int i = 0; i < n; i++) {
            if (arr[i] == first)
                count1++;
     
            else if (arr[i] == second)
                count2++;
        }
     
        if (count1 > n / 3){
            System.out.print(first+" ");
              flag=1;
        }
        if (count2 > n / 3){
            System.out.print(second+" ");
              flag=1;
        }
          if(flag==0)
           System.out.println("No Majority Element");
    }
     
    // Driver code
    public static void main(String args[])
    {
        int arr[] = { 2, 2, 3, 1, 3, 2, 1, 1 };
        int n = arr.length;
        findMajority(arr,n);
         
    }
}
 
// This code is contributed by Aman Chowdhury


Javascript


Python3
# Python program for the above approach
class Solution:
 
    # Function to find all elements that
    # occurs >= N/3 times in the array
    def majorityElement(self, a):
 
        # If array is empty return
        # empty list
        if not a:
            return []
 
        # Function to find the majority
        # element by Divide and Conquer
        def divideAndConquer(lo, hi):
            if lo == hi:
                return [a[lo]]
 
            # Find mid
            mid = lo + (hi - lo)//2
 
            # Call to the left half
            left = divideAndConquer(lo, mid)
 
            # Call to the right half
            right = divideAndConquer(mid + 1, hi)
 
            # Stores the result
            result = []
            for numbers in left:
                if numbers not in right:
                    result.append(numbers)
 
            result.extend(right)
 
            # Stores all majority elements
            ans = []
 
            for number in result:
                count = 0
 
                # Count of elements that
                # occurs most
                for index in range(lo, hi + 1):
                    if a[index] == number:
                        count += 1
 
                # If the number is a
                # majority element
                if count > (hi - lo + 1)//3:
                    ans.append(number)
 
            # Return the list of element
            return ans
 
        # Function Call
        print(divideAndConquer(0, len(a) - 1))
 
 
# Driver Code
if __name__ == "__main__":
 
    # Given array a[]
    a = [7, 7, 7, 3, 4, 4, 4, 6]
    object = Solution()
 
    # Function Call
    object.majorityElement(a)


Python3
# Python3 program for the above approach
from collections import Counter
 
# Function to find the number of array
# elements with frequency more than n/3 times
def printElements(arr, n):
 
    # Calculating n/3
    x = n//3
 
    # Counting frequency of every element using Counter
    mp = Counter(arr)
     
    # Traverse the map and print all
    # the elements with occurrence atleast n/3 times
    for it in mp:
        if mp[it] > x:
            print(it, end=" ")
 
 
# Driver code
arr = [7, 7, 7, 3, 4, 4, 4, 6]
 
# Size of array
n = len(arr)
 
# Function Call
printElements(arr, n)
 
# This code is contributed by vikkycirus


输出
2 1 

复杂度分析:

  • 时间复杂度: O(n*n) 需要一个嵌套循环,其中两个循环从头到尾遍历数组,因此时间复杂度为 O(n^2)。
  • 辅助空间: O(1) 因为任何操作都不需要额外的空间,所以空间复杂度是恒定的。

方法二(使用Hashmap):

  • 处理方式:这种方法在时间复杂度上有点类似于摩尔投票算法,但是在这种情况下,不需要摩尔投票算法的第二步。但像往常一样,这里的空间复杂度变为 O(n)。

在 Hashmap(key-value pair) 中,在 value 中,为每个元素 (key) 维护一个计数,并且每当计数大于数组长度的一半时,返回该 key(多数元素)。

C++

/* C++ program for finding out majority
element in an array */
#include 
using namespace std;
  
void findMajority(int arr[], int size)
{
    unordered_map m;
    for(int i = 0; i < size; i++)
        m[arr[i]]++;
    int flag = 0;
    for(auto i : m)
    {
        if(i.second > size / 3)
        {
            flag =1;
            cout << i.first << " ";
        }
    }
    if(flag == 0)
        cout << "No Majority element" << endl;
}
  
// Driver code
int main()
{
    int arr[] = { 2, 2, 3, 1, 3, 2, 1, 1};
    int n = sizeof(arr) / sizeof(arr[0]);
      
    // Function calling
    findMajority(arr, n);
  
    return 0;
}
 
// This code is contributed by Aman Chowdhury

Java

import java.util.HashMap;
 
/* Program for finding out majority element in an array */
 
class MajorityElement
{
    private static void findMajority(int[] arr)
    {
        HashMap map = new HashMap();
        int flag=0;
        for(int i = 0; i < arr.length; i++) {
            if (map.containsKey(arr[i])) {
                    int count = map.get(arr[i]) +1;
                    if (count > arr.length /3) {
                        System.out.print(arr[i]+" ");
                          flag=1;
                    } else
                        map.put(arr[i], count);
 
            }
            else
                map.put(arr[i],1);
            }
              if(flag==0)
                System.out.println(" No Majority element");
    }
 
 
    /* Driver program to test the above functions */
    public static void main(String[] args)
    {
        int a[] = new int[]{2, 2, 3, 1, 3, 2, 1, 1};
         
        findMajority(a);
    }
}
 
// This code is contributed by Aman Chowdhury
输出
1 2 

复杂度分析:

  • 时间复杂度: O(n) 需要遍历一次数组,所以时间复杂度是线性的。
  • 辅助空间: O(n) 因为哈希图需要线性空间。

方法三(摩尔投票算法):

这个想法是基于摩尔的投票算法。我们首先找到两个候选人。然后我们检查这两个候选人中是否有任何一个实际上是多数。以下是上述方法的解决方案。

C++

// C++ program to find Majority
// element in an array
#include 
using namespace std;
  
// Function to find Majority element
// in an array
void findMajority(int arr[], int n){
      int count1 = 0, count2 = 0;
    int first=INT_MAX, second=INT_MAX;
    int flag=0;
    for (int i = 0; i < n; i++) {
  
        // if this element is previously seen,
        // increment count1.
        if (first == arr[i])
            count1++;
  
        // if this element is previously seen,
        // increment count2.
        else if (second == arr[i])
            count2++;
      
        else if (count1 == 0) {
            count1++;
            first = arr[i];
        }
  
        else if (count2 == 0) {
            count2++;
            second = arr[i];
        }
  
        // if current element is different from
        // both the previously seen variables,
        // decrement both the counts.
        else {
            count1--;
            count2--;
        }
    }
  
    count1 = 0;
    count2 = 0;
  
    // Again traverse the array and find the
    // actual counts.
    for (int i = 0; i < n; i++) {
        if (arr[i] == first)
            count1++;
  
        else if (arr[i] == second)
            count2++;
    }
      
    if (count1 > n / 3){
        cout << first << " ";
          flag=1;
    }
    if (count2 > n / 3){
        cout << second << " ";
          flag=1;
    }
      if(flag==0){
          cout << "No Majority Element" << endl;
    }
}
   
int main() {
 
    int arr[] = { 2, 2, 3, 1, 3, 2, 1, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    // Function calling
    findMajority(arr, n);
  
    return 0;
}
 
// This code is contributed by Aman Chowdhury

Java

// Java program to find if any element appears
// more than n/3.
class GFG {
     
    static void findMajority(int arr[], int n)
    {
        int count1 = 0, count2 = 0;
        int flag=0;
        // take the integers as the maximum
        // value of integer hoping the integer
        // would not be present in the array
        int first = Integer.MIN_VALUE;;
        int second = Integer.MAX_VALUE;
     
        for (int i = 0; i < n; i++) {
     
            // if this element is previously
            // seen, increment count1.
            if (first == arr[i])
                count1++;
     
            // if this element is previously
            // seen, increment count2.
            else if (second == arr[i])
                count2++;
         
            else if (count1 == 0) {
                count1++;
                first = arr[i];
            }
     
            else if (count2 == 0) {
                count2++;
                second = arr[i];
            }
     
            // if current element is different
            // from both the previously seen
            // variables, decrement both the
            // counts.
            else {
                count1--;
                count2--;
            }
        }
     
        count1 = 0;
        count2 = 0;
     
        // Again traverse the array and
        // find the actual counts.
        for (int i = 0; i < n; i++) {
            if (arr[i] == first)
                count1++;
     
            else if (arr[i] == second)
                count2++;
        }
     
        if (count1 > n / 3){
            System.out.print(first+" ");
              flag=1;
        }
        if (count2 > n / 3){
            System.out.print(second+" ");
              flag=1;
        }
          if(flag==0)
           System.out.println("No Majority Element");
    }
     
    // Driver code
    public static void main(String args[])
    {
        int arr[] = { 2, 2, 3, 1, 3, 2, 1, 1 };
        int n = arr.length;
        findMajority(arr,n);
         
    }
}
 
// This code is contributed by Aman Chowdhury

Javascript


输出
2 1 

复杂度分析:

  • 时间复杂度: O(n) 算法的第一遍遍历对 O(n) 有贡献的数组,另一个 O(n) 用于检查 count1 和 count2 是否大于 floor(n/3) 次。
  • 辅助空间: O(1) 因为不需要额外的空间所以空间复杂度是恒定的

方法四:

方法:解决问题的思路是采用分而治之的技术。请按照以下步骤解决问题:

  1. 初始化函数majorityElement(),将自向右的任何索引返回大多数元件的计数在数组中。
  2. 将给定的数组arr[]分成两半,并重复将其传递给函数manyElement()
  3. 分别将lowhigh初始化为0(N – 1)
  4. 使用以下步骤计算多数元素:
    • 如果低 = 高:返回arr[low]作为多数元素。
    • 找到中间指数,比如mid (= (low + high)/2 )。
    • 递归地调用左右子数组作为manyElement(arr, low, mid)mostElement(arr, mid + 1, high)
    • 完成上述步骤后,合并两个子数组并返回多数元素。
  5. 每当找到所需的多数元素时,将其附加到结果列表中。
  6. 打印存储在列表中的所有多数元素。

下面是上述方法的实现:

蟒蛇3

# Python program for the above approach
class Solution:
 
    # Function to find all elements that
    # occurs >= N/3 times in the array
    def majorityElement(self, a):
 
        # If array is empty return
        # empty list
        if not a:
            return []
 
        # Function to find the majority
        # element by Divide and Conquer
        def divideAndConquer(lo, hi):
            if lo == hi:
                return [a[lo]]
 
            # Find mid
            mid = lo + (hi - lo)//2
 
            # Call to the left half
            left = divideAndConquer(lo, mid)
 
            # Call to the right half
            right = divideAndConquer(mid + 1, hi)
 
            # Stores the result
            result = []
            for numbers in left:
                if numbers not in right:
                    result.append(numbers)
 
            result.extend(right)
 
            # Stores all majority elements
            ans = []
 
            for number in result:
                count = 0
 
                # Count of elements that
                # occurs most
                for index in range(lo, hi + 1):
                    if a[index] == number:
                        count += 1
 
                # If the number is a
                # majority element
                if count > (hi - lo + 1)//3:
                    ans.append(number)
 
            # Return the list of element
            return ans
 
        # Function Call
        print(divideAndConquer(0, len(a) - 1))
 
 
# Driver Code
if __name__ == "__main__":
 
    # Given array a[]
    a = [7, 7, 7, 3, 4, 4, 4, 6]
    object = Solution()
 
    # Function Call
    object.majorityElement(a)
输出
[7, 4]

时间复杂度: O(N*log N)
辅助空间: O(log N)

另一种方法:使用内置Python函数:

  • 使用 Counter()函数计算每个元素的频率。
  • 遍历频率数组并打印所有出现次数超过 n/3 次的元素。

下面是实现:

蟒蛇3

# Python3 program for the above approach
from collections import Counter
 
# Function to find the number of array
# elements with frequency more than n/3 times
def printElements(arr, n):
 
    # Calculating n/3
    x = n//3
 
    # Counting frequency of every element using Counter
    mp = Counter(arr)
     
    # Traverse the map and print all
    # the elements with occurrence atleast n/3 times
    for it in mp:
        if mp[it] > x:
            print(it, end=" ")
 
 
# Driver code
arr = [7, 7, 7, 3, 4, 4, 4, 6]
 
# Size of array
n = len(arr)
 
# Function Call
printElements(arr, n)
 
# This code is contributed by vikkycirus
输出
7 4 

时间复杂度: O(N)

辅助空间: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程