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

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

时间:2015-09-03 19:05:47      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

  题目来源《剑指offer》面试题29、《编程之美》2.3

  题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.

  解法1:数组中有一个数字出现的次数超过了一半,也就是说它出现的次数比其他所有数字出现次数的和还要多。因此我们可以考虑在遍历数组的时候保留两个值:一个是数组中的一个数字,一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们保存的数字不同,则次数减1。如果次数为零,我们需要保存下一个数字,并把次数设为1。由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么我们要找的数字肯定是最后一次把次数设为1时对应的数字。

  

bool g_invalid_input = false;

bool CheckInvalidArray(int* numbers, int len) {
    g_invalid_input = fasle;

    if (numbers == NULL || len <= 0)
        g_invalid_input = true;

    return g_invalid_input;
}


bool CheckMoreThanHalf(int* numbers, int len, int candidate) {
    int times = 0;

    for (int i = 0; i < len; i++)
        if (numbers[i] == candidate)
            times++;

    if (times * 2 < len) {
        g_invalid_input = true;
        return fasle;
    }

    return true;
}

int MoreThanHalf(int* numbers, int len) {
    if (CheckInvalidArray(numers, len))
        return 0;

    int candidate = numbers[0];
    int times = 1;

    for (int i = 1; i < len; i++) {
        if (times == 0) {
            candidate = numbers[i];
            times = 1;
        } else {
            if (candidate == numbers[i])
                times++;
            else 
                times--;
        }
    }


    if(!MoreThanHalf(numbers, len, candidate))
        return 0;

    return candidate;
}

 

解法二:数组中有一个数字出现的次数超过了数组长度的一半。如果把这个数组排序,那么排序之后位于数组中间的数字一定就是那个出现次数超过长度一半的数字。

 

bool g_invalid_input = false;

bool CheckInvalidArray(int* numbers, int len) {
    g_invalid_input = fasle;

    if (numbers == NULL || len <= 0)
        g_invalid_input = true;

    return g_invalid_input;
}


bool CheckMoreThanHalf(int* numbers, int len, int candidate) {
    int times = 0;

    for (int i = 0; i < len; i++)
        if (numbers[i] == candidate)
            times++;

    if (times * 2 < len) {
        g_invalid_input = true;
        return fasle;
    }

    return true;
}

int Partition(int *numbers, int start, int end) {
    int pivot = numbers[end];
    int p = start - 1;
    int j = p;
    for (; j < end; j++) {
        if (numbers[j] <= pivot) {
            swap(a[++p], a[j]);
        }
    }

    swap(a[++p], a[end]);
    return p;
}

int MoreThanHalf(int* numbers, int len) {
    if (CheckInvalidArray(numbers, len))
        return 0;

    int k = len / 2;
    
    int start = 0;
    int end = len - 1;
    int pos = Partition(numbers, start, end);
    while (pos != k) {
        if (pos > k) {
            end = pos - 1;
            pos = Partition(numbers, start, end);
        } else {
            start = pos + 1;
            pos = Partition(numbers, start, end);
        }
    } 

    int candidate = numbers[k];
    if (CheckMoreThanHalf(numbers, len, candidate))
        candidate = 0;
    return candidate;
}

 

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

标签:

原文地址:http://www.cnblogs.com/vincently/p/4780409.html

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