在O(n)的时间复杂度内找出数组中出现次数超过了一半的数

本文介绍了一种寻找数组中出现次数超过一半的元素的算法,并提供了Java和C语言的实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目来自程序员面试笔试宝典:P303
采用阵地攻守的思想: 第一个数字作为第一个士兵,守阵地;count = 1; 遇到相同元素,count++; 遇到不相同元素,即为敌人,同归于尽,count–;当遇到count为0的情况,又以新的i值作为守阵地的士兵,继续下去,到最后还留在阵地上的士兵,有可能是主元素。 再加一次循环,记录这个士兵的个数看是否大于数组一半即可。
本题O(n)的思想是,定义两个变量temp和count,每次循环时,如果array[i]的值等于temp,则count自增一,如不等并且count>0,则count自减一,若array[i]的值不等于temp并且count不大于0,重新对temp赋值为当前array[i],count赋值为1。
如存在大于一半的数,直接返回temp就是了,但测试数据中有不存在的情况,所以最后又来了一遍校验,检查当前temp值是否出现过一半以上。
Java:

public int MoreThanHalfNum_Solution(int [] array) {
       int count = 0;
       int temp = 0;
       for (int i = 0; i < array.length; i++) {
           if (array[i] == temp) {
               count++;
           } else if (count > 0) {
               count--;
           } else {
               temp = array[i];
               count = 1;
           }
       }
       //验证
       count=0;
       for(int i=0;i<array.length;i++){
           if(array[i]==temp)
           count++;
       }
       return count > array.length/2 ? temp : 0;
   }

C语言:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int aawe(int *num,int len)
{
    int candidate=0;
    int count=0;
    int i;
    for(i=0;i<len;i++)
    {
        if(count==0)
        {
            candidate=num[i];
            count=1;
        }
        else
        {
            if(candidate == num[i])
                count++;
            else
                count--;
        }
    }

    count=0;
       for(i=0;i<len;i++){
           if(num[i]==candidate)
           count++;
       }
       return count > len/2 ? candidate : -1;

}

int main()
{
    int c[8]={2,0,70,40,4,24,6,2};
    int i;
    printf("%d   ",aawe(c,8) );

    system("PAUSE");
    return 0;
}

引用:

http://www.nowcoder.com/questionTerminal/e8a1b01a2df14cb2b228b30ee6a92163

在没有额外存储空间的情况下找到出现次数超过一半一个经典的计算机科学问题,通常使用“快速选择”或“三向切分”等在线算法,但这些都比较复杂。对于这个问题,更常见的做法是利用“摩尔投票法”(Majority Element),这个算法可以在O(n)时间复杂度内解决,其中n是矩阵(数组)的长度。 以下是使用Python一个简单示例,假设我们有一个二维矩阵(实际上是一维数组,因为矩阵通常是行主序访问),并假定我们知道元素都是非负整: ```python def majority_element(matrix): if not matrix or len(matrix) == 0: return None num_elements = len(matrix[0]) count = [0] * (num_elements + 1) for row in matrix: for element in row: count[element] += 1 # 使用摩尔投票法,候选初始为第一个元素 candidate, count_candidate = matrix[0][0], count[matrix[0][0]] # 更新候选和计,直到只有一个元素大于一半 for i in range(1, num_elements + 1): if count[i] > count_candidate: candidate, count_candidate = i, count[i] # 检查候选是否满足超过一半的条件 for row in matrix: if row.count(candidate) != num_elements / 2: return None return candidate # 示例 matrix_example = [[1, 1, 1], [2, 2, 1], [3, 3, 2]] print(majority_element(matrix_example)) # 输出:2 或者 3(任意一个) ``` 注意,这个函返回的是一个候选元素,如果矩阵中有多个元素出现了超过,它只能返回其中一个。实际应用中,如果有多个这样的元素,并且你需要确定它们的具体位置,可能需要进一步分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值