数据结构练习(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个数字中必有一个,然后稍加判断问题解决。

 

你可能感兴趣的:(数据结构)