《剑指offer》-数组中出现次数超过一半的数字

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

class Solution {
public:
    /*
    最开始的想法:排序后,假如存在元素满足题目条件,那么中间位置的元素就是这样的元素,那么双向增长,判断增长停滞点之间的长度
    缺点是复杂度过高
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        sort(numbers.begin(), numbers.end());
        if(numbers.size()==0){
            return 0;
        }
        if(numbers.size()==1){
            return numbers[0];
        }
        int mid = (numbers.size()-1)/2;
        int low=mid, high=mid+1;
        while(low>=0 && high<=numbers.size()-1){
            if(numbers[low]==numbers[mid]){
                low--;
            }
            if(numbers[high]==numbers[mid]){
                high++;
            }
        }
        int len = high - low + 1;
        if(len>numbers.size()/2) return numbers[mid];
        return 0;
    }*/

        // 讨论帖中的做法,个人理解为:假如有某个数字出现次数超过一半,那么它们每个元素有一口气,我累计收集这些气(遍历):
        // 遇到这个元素,气+1;遇到其他元素,气-1;如果气等于0,则更新气味为新元素的气;
        // 最后验证一下这个气是否为所求:因为留下来的气,对应元素出现次数可以少于一半。
    int MoreThanHalfNum_Solution(vector<int> numbers){
        int n = numbers.size();
        if (n == 0) return 0;

        int num = numbers[0], count = 1;
        for (int i = 1; i < n; i++){
            if (numbers[i] == num) {
                count++;
            }
            else{
                count--;
            }
            if (count == 0){
                num = numbers[i];
                count = 1;
            }
        }

        //verification
        count = 0;
        for (int i = 0; i < n; i++){
            if (numbers[i] == num){
                count++;
            }
        }
        if (count * 2 > n){
            return num;
        }
        return 0;
    }
};
时间: 2024-09-16 20:10:58

《剑指offer》-数组中出现次数超过一半的数字的相关文章

基于Java代码实现数字在数组中出现次数超过一半_java

下文通过几种方法给大家介绍java数组数字出现次数,具体内容如下所示: 方法一: 数组排序,然后中间值肯定是要查找的值. 排序最小的时间复杂度(快速排序)O(NlogN),加上遍历. 方法二: 使用散列表的方式,也就是统计每个数组出现的次数,输出出现次数大于数组长度的数字. 方法三: 出现的次数超过数组长度的一半,表明这个数字出现的次数比其他数出现的次数的总和还多. 考虑每次删除两个不同的数,那么在剩下的数中,出现的次数仍然超过总数的一般,不断重复该过程,排除掉其他的数,最终找到那个出现次数超过

剑指Offer之和为S的两个数字

题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 输入: 每个测试案例包括两行: 第一行包含一个整数n和k,n表示数组中的元素个数,k表示两数之和.其中1 <= n <= 10^6,k为int 第二行包含n个整数,每个数组均为int类型. 输出: 对应每个测试案例,输出两个数,小的先输出.如果找不到,则输出"-1 -1" 样例输入: 6 15 1 2 4 7 11 15 样例输出:

找出数组中出现次数最多的数字

package cc; //找出数组{ 3, 4, 1, 5, 3, 1, 4, 5, 4, 3 }中出现次数最多的数字 //1 建立一个新数组,长度与原数组一致,然后将每个数字出现的次数存入此数组 //2 找出此数组中的最大值,尤其关注的是此最大值的下标 public class ArrayCount { public static void main(String[] args) { int test[] = new int[] { 1, 2, 3, 2, 3, 3 }; Arr arr =

剑指offer系列之二十七:数组中出现次数超过一半的数

题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如果不存在则输出0. 思路分析:由于是一个数字,因为其次数超过1,那么其出现的出现综合肯定实际大于其他所有数字之和的.因为如此,我们可以设置一个变量用于辨识这个变量,遇到相同的数字就把次数增加1,如果没有没有遇到就把次数减少1,那么肯定次数有可能变为0,因为没有遇到相同的.因为那个数字的次数出现了超

剑指offer系列之三:在二维数组中查找元素

题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 由于题目条件的成立,所以使得这道题可以使用对角线的方法完成,可以从右上角的元素考虑,如果目标查找元素小于右上角的元素,那么不可能在右上角元素所在的列,如果目标大于剩余列的右上角的元素,那么不可能在该右上角元素所在的行.依照这个规律,就可以完成目标元素的查找(参考剑指offer书中的思路).基于此,我写出如下的代码(已被

[剑指Offer] 第4章课后题详解

[剑指Offer] 第4章课后题详解 目录 剑指Offer 第4章课后题详解 目录 二叉树的镜像 分析 解法 拓展 判断前序遍历 分析 解法 拓展 字符的组合 分析 解答 正方体的顶点 分析 解法 8个皇后 分析 解法 二叉树的镜像 本题为<剑指Offer>"面试题19:二叉树的镜像"一节中的"本题拓展". 请完成一个函数,输入一个二叉树,该函数输出它的镜像,要求使用循环的方法,不能用递归.二叉树节点定义如下: struct BinaryTreeNode

[剑指Offer]5.二维数组中的查找

题目 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 思路 [算法系列之三十三]杨氏矩阵 代码 /*--------------------------------------- * 日期:2015-07-19 * 作者:SJF0115 * 题目: 5.二维数组中的查找 * 网址:http://www.nowcoder.com/books/coding-interviews/a

[剑指Offer]40.数组中只出现一次的数字

题目 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路 我们直到异或的性质: 任何一个数字异或他自己都等于0. 所以说我们如果从头到尾依次异或每一个数字,那么最终的结果刚好只出现一次的数字,因为成对出现的两次的数字全部在异或中抵消了. 这道题中有两个数字只出现一次.这样的话我们得到的结果就是这两个数字的异或结果.因此我们想办法把原数组分成两个子数组,使得每个子数组包含一个只出现一次的数字.这样我们就可以对这两个子数组分别异或,就能得到两个只出现一

剑指offer系列之四十九:数组中重复的数字

题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3. 此题的思路还是比较简单的,与之前找出只出现一次的数字的题目有些类似,基本思路还是创建一个Map容器,key是出现的数字,value则是该数字出现的次数.在遍历数组的过程中,只要容器中已经出现了该数字,那么就直接返回给数组,