码迷,mamicode.com
首页 > 编程语言 > 详细

29 - 数组中出现次数超过一半的数字

时间:2015-07-27 19:07:30      阅读:99      评论:0      收藏:0      [点我收藏+]

标签:出现次数   数组   

题目描述:http://ac.jobdu.com/problem.php?pid=1370
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。


直观想法是,先排序O(nlgn),那么下标是 n/2 的位置上一定是超过数组长度一半的数字。

另一种思路是:
用快排里面的划分函数,随机选一个元素,将比它小的交换到左侧,比它大的交换到右侧,最后交它交换到左右的中间。如果这个元素被交换到n/2的位置,那么该元素就是中位数;如果元素的位置index小于n/2,那么中位数在它的右侧,去右侧(index, n)查找划分;反之在左侧(0,index)查找划分。时间复杂度 O(n),但是会修改原数组的内容。

第三种思路是:
一个数字出现的次数超过数组长度的一半,说明它比数组中其他所有数字出现的次数还要多。
我们在遍历数组时,保存2个值,一个数字和次数。

  • 如果下一个数字和保存的数字相同,次数+1
  • 如果下一个数字和保存的数字不同,次数-1
  • 如果次数为0, 保存下一个数字

因此要找的数字,是最后一次设置的数字。
时间复杂度O(n),且不改变数组内容。

#include <iostream>
using namespace std;
bool IsValid = true;
int MoreThanHalfNum(int* nums, int length) {
    if (nums == NULL || length <= 0) {
        IsValid = false;
        return 0;
    }
    int result = nums[0];
    int times = 1;
    for(int i = 1; i < length; i++) {
        if (times == 0) {
            result = nums[i];
            times = 1;
        } else {
            if (nums[i] == result)
                times++;
            else
                times--;
        }
    }
    return result;
}
int main() {
    int a[] = {1,2,4,2,5,2,2,6,3,2,2};
    int result = MoreThanHalfNum(a, sizeof(a)/sizeof(a[0]));
    if (result == 0 && IsValid == false)
        cout << "Input Error." << endl;
    else
        cout << result << endl;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

29 - 数组中出现次数超过一半的数字

标签:出现次数   数组   

原文地址:http://blog.csdn.net/quzhongxin/article/details/47086955

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!