• 剑指offer——数组中出现次数超过一半的数字(c++)


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

    思路一
    遍历数组是保存两个值:一个是数字中的一个数字,另一个是次数。当遍历到下一个数字的时候,如果下一个数字和之前保存的数字相等,则次数加1;如果不同,则次数减1;如果次数为零,那么我们需要保存下一个数字,并把次数设置为1。
    由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么要找的数字肯定是最后一次把次数设置为1时对应的数字。

    class Solution {
    public:
    int MoreThanHalfNum_Solution(vector<int> nums) {
    if(nums.size() <= 0){
    return 0;
    }
    int res = nums[0];
    int times = 1;
    for(int i = 1; i < nums.size(); ++i){
    if(times == 0){
    res = nums[i];
    times = 1;
    }
    else if(nums[i] == res){
    times++;
    }
    else{
    times--;
    }
    }
    if(!CheckMoreHalf(nums, res)){
    res = 0;
    }
    return res;
    }
    private:
    //判断这个数字是否出现次数超过一半
    bool CheckMoreHalf(vector<int>& nums, int result){
    int times = 0;
    for(int i = 0; i < nums.size(); ++i){
    if(nums[i] == result){
    ++times;
    }
    }
    if(times * 2 <= nums.size()){
    return false;
    }
    return true;
    }
    };
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    思路二
    基于快排的思想。将数组排序后,中间的数字即为要寻找的数字,那么,这个数据就是统计学上的中位数,即长度为n的数组中第n/2大的数字。
    在随机快排中,随机选择一个数字,调整数组顺序,如果其下标刚好是n/2,那么就找到了中位数;如果其下标小于n/2,则中位数应该在它的右边;如果其下标大于n/2,则中位数应该在它的左边。

    class Solution {
    public:
    int MoreThanHalfNum_Solution(vector<int> nums) {
    int n = nums.size();
    if(n <= 0){
    return 0;
    }
    int left = 0, right = n - 1;
    int mid = n / 2;
    int index = Partition(nums, left, right);
    while(index != mid){
    if(index > mid){
    right = index - 1;
    index = Partition(nums, left, right);
    }
    else{
    left = index + 1;
    index = Partition(nums, left, right);
    }
    }
    int res = nums[mid];
    if(!CheckMoreHalf(nums, res)){
    res = 0;
    }
    return res;
    }
    private:
    int Partition(vector<int>& nums, int left, int right){
    int pivot = nums[right];
    int tail = left - 1;
    for(int i = left; i < right; ++i){
    if(nums[left] <= pivot){
    ++tail;
    if(tail != i)
    swap(nums[tail], nums[i]);
    }
    }
    swap(nums[tail+1], nums[right]);
    return tail+1;
    }
    bool CheckMoreHalf(vector<int>& nums, int result){
    int times = 0;
    for(int i = 0; i < nums.size(); ++i){
    if(nums[i] == result){
    ++times;
    }
    }
    if(times * 2 <= nums.size()){
    return false;
    }
    return true;
    }
    };
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53

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

  • 相关阅读:
    MySQL视图——学习笔记及实验
    小学生四则运算自动刷题库优化升级
    软件工程小项目——小学生四则运算自动刷题库
    笔记--运算符、表达式和语句
    笔记--基本数据类型与数组
    笔记--java入门
    原因: java.lang.ClassNotFoundException: Hello
    使用gopm代替go get 解决go包卡慢的问题
    调用微信截图功能c# 截图带扩展名
    如何用golang搜索抓取淘宝商品
  • 原文地址:https://www.cnblogs.com/ly570/p/11109196.html
Copyright © 2020-2023  润新知