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

    -------------------------------------------------------

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

    -------------------------------------------------------

  • 相关阅读:
    音频播放
    控制器的创建和控制器View的创建
    UIWebView之获取所点位置的图片(放大webView中的图片)
    SQLite的应用
    数据库操作(SQLite)
    计算文件(文件夹)大小
    本人专访微信魔法表情“米悠”作者流星剑
    Swift给每个开发者赢取500万的机会!不看一生后悔。
    疯狂猜图产品和盈利模式分析
    开发者改变世界的初心!
  • 原文地址:https://www.cnblogs.com/kedebug/p/2823308.html
Copyright © 2020-2023  润新知