• 数组中超过一半的数字


    【问题】数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

    【思路】首先,第一个思路,我们不考虑空间复杂度,这种在笔试时最好用,使用一个哈希表,然后遍历,由于unordered_map中不允许重复的key,因此每遍历到相同的key,value就加一。然后判断这个值大不大于数组的一半,如果大于,直接返回即可,否则返回零。

    class Solution {
    public:
        int MoreThanHalfNum_Solution(vector<int> numbers) {
            unordered_map<int, int> hash_map;
            if(numbers.size() == 1) return 1;
            for(auto i: numbers){
                hash_map[i]++;
                if(hash_map[i] > (numbers.size() / 2)){
                    return i;
                }
            }
            return 0;
        }
    };

    另一种思路时,先对整个序列进行排序操作,如果数组中一个数的数量超过这个数组的一半,那么对整个数组排序后,这个数一定位于数组的中间位置!那么既然要排序,我们这里使用快排对数组进行排序,O(Nlogn),虽然有人可以优化到O(n),但是代码太多太复杂了!经过排序后,我们首先获得中间位置的值,然后遍历整个排序数组,统计这个值的个数,如果确实大于size/2,则返回这个数的个数!既然你要学算法,就尽量别调库了,老老实实自己写个快排!

    class Solution {
    public:
        vector<int> qs_partition(vector<int>& list, int L, int R){
            int more = R;   // 选取最后一个数为分界点
            int less = L - 1;
            int cur = L;
            vector<int> res(2);
            while(cur < more){
                if(list[cur] < list[R]){
                    swap(list[++less], list[cur++]);
                }else if(list[cur] > list[R]){
                    swap(list[--more], list[cur]);  
                    // 交换后cur有可能小于中间值,还需要再次交换,因此cur不进行自加
                }else{
                    cur++;
                }
            }
            swap(list[more], list[R]);
            res[0] = less+1;
            res[1] = more;
            return res;
        }
        // 经典快排
        void QuickSort(vector<int>& list, int L, int R){
            if(list.size() < 2) return;
            if(L < R){
                vector<int> p = qs_partition(list, L, R);
                QuickSort(list, L, p[0]-1);
                QuickSort(list, p[1]+1, R); // 递归处理其他部分
            }
        }
    
        int MoreThanHalfNum_Solution(vector<int> numbers) {
            if(numbers.size() == 0) return 0;
            int size = numbers.size();
            QuickSort(numbers, 0, size-1);
            int mid = size / 2;   // 获得中间位置的值
            int count = 0;
            for(auto num: numbers){
                if(num == numbers[mid]){
                    count++;     // 统计中间位置值的数量 
                    if(count > (size / 2)){
                        return num;
                    }
                }
            }
            return 0;
        }
    };
  • 相关阅读:
    火狐下,td 的 bug;
    在centos6.3用yum安装redis
    Linux系统下修改环境变量PATH路径的三种方法
    网络文件常常提到类似"./run.sh"的数据,这个命令的意义是什么?
    DataGridView的自定义列排序
    【Linux】linux常用基本命令
    用户名 不在 sudoers文件中,此事将被报告。(转)
    将XML文件中的内容转换为Json对象
    C# 加载xml文档文件及加载xml字符串
    增加不存在的列
  • 原文地址:https://www.cnblogs.com/zhudingtop/p/11349737.html
Copyright © 2020-2023  润新知