数据结构练习(35)数组中出现次数超过一半的数字

http://zhedahht.blog.163.com/blog/static/25411174201085114733349/

思路:

编程之美上面的一道题“寻找水王”。百度电话面试的时候也恰巧问到,当时比较紧张,怎么也想不出来。

其实我觉得这种类似于智力题的题目还是需要一定的积累的,再聪明的人如果没有经过一定的训练也很难想出来解法。

《编程珠玑》上面提到过“最大子段和”问题,现在看起来十分简单,那是因为自己反复训练过,如果看到这个最优解的获取过程,

还是十分艰辛的,是很多人经过很长时间才弄出来的一个问题。

 

#include <iostream>
using namespace std;

bool SolveProblem(int n[], int len, int& x)
{
    if (n == nullptr || len <= 0)
        return false;

    int times = 0;
    int result;
    for (int i = 0; i < len; ++i)
    {
        if (times == 0)
            result = n[i], ++times;
        else if (result == n[i])
            ++times;
        else if (result != n[i])
            --times;
    }

    times = 0;
    for (int i = 0; i < len; ++i)
        if (result == n[i])
            ++times;

    if (times * 2 > len)
    {
        x = result;
        return true;
    }
    else
        return false;
}

int main()
{
    int n[] = {1, 2, 1, 3, 1, 4, 1};
    int result;

    if (SolveProblem(n, 7, result))
        cout << result << endl;
    else
        cout << "failed to find" << endl;

    return 0;
}

 

变型1:

随着Tango的发展,管理员发现,“超级水王”没有了。统计结果表明,有3个发帖很多的ID,他们的发帖数目都超过了帖子总数目N的1/4。你能从发帖ID列表中快速找出他们的ID吗?

bool SolveProblemHarder(int n[], int len, int& x, int& y, int& z)
{
    if (n == nullptr || len <= 0)
        return false;
    
    int times[3];
    int candidate[3];

    times[0] = times[1] = times[2] = 0;

    for (int i = 0; i < len; ++i)
    {
        if (times[0] == 0)
            candidate[0] = n[i], ++times[0];
        else if (times[1] == 0)
            candidate[1] = n[i], ++times[1];
        else if (times[2] == 0)
            candidate[2] = n[i], ++times[2];
        else if (candidate[0] == n[i])
            ++times[0];
        else if (candidate[1] == n[i])
            ++times[1];
        else if (candidate[2] == n[i])
            ++times[2];
        else
            --times[1], --times[2], --times[3];
    }
    x = candidate[0], y = candidate[1], z = candidate[2];
    return true;
}

变型2:

如果这个数字恰好出现为一半应该如何解决?

思路:

拿掉2个不相同的数字,按照第一种方法求出来result,如果满足条件则返回,如果不满足则拿掉的2个数字中必有一个,然后稍加判断问题解决。

 

posted @ 2012-12-18 14:54  kedebug  阅读(229)  评论(0编辑  收藏  举报