面试题29_数组中出现次数超过一半的数字

题目描述

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

解题思路

出现超过一半的数,一定是排好序的数组的中位数,即位置为 n/2 的数。

找到这个中位数,然后,遍历一次,判断是否出现次数超过一半,若是,则返回true,否则,没有这样的数。

关键在于如何得到这个中位数?

两种思路,

1、对数组进行排序,直接取中位数,时间复杂度O(nlogn);

2、利用快排的partition算法,得到位置为n/2的数,即中位数,时间复杂度O(n);

实现代码

<span style="font-size:18px;">//O(nlogn)解法
class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
    	int result=0;
        if(numbers.empty())
            return 0;
        sort(numbers.begin(),numbers.end());
        int len = numbers.size();
        int num = numbers[len/2];
        int count = 0;

        for(int i=0;i<len;i++)
        {
        	if(numbers[i] == num)
                count++;
        }

        if(count > len/2)
        {
        	result = num;
            return result;
        }
        else
            return 0;
    }
};

//O(n)解法
class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
    	int result=0;
        if(numbers.empty())
            return 0;
        //sort(numbers.begin(),numbers.end());
        int len = numbers.size();

        int mid = len >> 1;
        int start = 0;
        int end = len-1;
        int index = partition(numbers,start, end);
        while(index != mid)
        {
        	if(index > mid)
            {
            	end = index-1;
                index = partition(numbers,start,end);
            }
            else
            {
            	start = index+1;
                index = partition(numbers,start,end);
            }
        }

        int num = numbers[index];
        int count = 0;

        for(int i=0;i<len;i++)
        {
        	if(numbers[i] == num)
                count++;
        }

        if(count > len/2)
        {
        	result = num;
            return result;
        }
        else
            return 0;
    }

    int partition(vector<int> numbers, int low, int high)
    {
    	int pivotloc = low;
        int temp = numbers[low];

        while(low < high)
        {
        	while(low < high && numbers[high] >= temp)
                high--;
            if(low < high)
            {
            	numbers[low] = numbers[high];
                low++;
            }

            while(low < high && numbers[low] <= temp)
                low++;
            if(low < high)
            {
            	numbers[high] = numbers[low];
                high--;
            }
        }
        numbers[low] = temp;
        return low;
    }
};
</span>
时间: 2024-10-13 07:06:12

面试题29_数组中出现次数超过一半的数字的相关文章

面试题29 数组中出现次数超过一半的数字

题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如果不存在则输出0. 1 class Solution { 2 public: 3 int MoreThanHalfNum_Solution(vector<int> numbers) { 4 if (numbers.size() == 0) 5 return 0; 6 int result = n

面试题五 数组中出现次数超过一半的数字 时间为O(n)

也就是说 该数字出现的次数比其他所有数字出现次数的和还要多. 因此可以保存两个值,一个数字,一个次数. 遍历时 1.如果数字相同,count++ 2.如果count == 0 count = 1 number替换 3.如果不相同 count-- int main(){ int array[] = {3, 2, 3, 1, 3, 4}; int number = array[0], count = 0; for (int i = 1; i < 6; i++){ if (count == 0){ c

面试题:数组中出现次数超过一半的数字

题目描述: 方法1:哈希表 import java.util.HashMap; public class Solution { public int MoreThanHalfNum_Solution(int [] array) { HashMap<Integer,Integer> map = new HashMap<>(); for(int i=0;i<array.length;i++){ Integer key=array[i]; Integer value=map.get

剑指OFFER----面试题39. 数组中出现次数超过一半的数字

链接:https://leetcode-cn.com/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/ 思路: cnt记录个数,val记录值:遍历数组,若等于val,则cnt++,否则cnt--,若cnt为0,则重置,最后val即为结果. 代码: class Solution { public: int majorityElement(vector<int>& nums) { int cnt =

剑指offer面试题29:数组中出现次数超过一半的数字

题目:数组中有一个数字出现的次数超过数组长度的一般,请找出这个数字,例如输入一个长度为9的数组(1,2,3,2,2,2,5,4,2,).由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 个人第一眼想法是通过一个sort函数,再判断中间那数出现次数,只要出现多于n/2,就直接输出. 一般来说,最为直观的算法面试官都不会满意,那么有没有更优的算法呢? 这种算法是受快速排序算法的启发.在随机快速排序算法中,我们现在数组中随机选择一个数字,然后调整数组中数字的顺序,使得比选中的数字小的数字

剑指Offer对答如流系列 - 数组中出现次数超过一半的数字

面试题39:数组中出现次数超过一半的数字 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1, 2, 3, 2, 2, 2, 5, 4, 2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 问题分析 大家最容易想到的思路是 数字次数超过一半,则说明排序之后数组中间的数字一定就是所求的数字. 既然是数组,要牵扯到排序,大家一般都会选用经典快速排序或者随机快速排序.随机快速排序由于每次划分的依据是从数组随机选出的,所以数据状况对它

编程算法 - 数组中出现次数超过一半的数字 代码(C)

数组中出现次数超过一半的数字 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 数组中有一个数字出现的次数超过数组长度的一半, 请找出这个数字. 1. 使用高速排序(QuickSort)的方法, 把中值(middle)和索引(index)匹配, 输出中值, 并检測是否符合要求. 2. 使用计数方法依次比較. 代码:  方法1: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */

【剑指offer】Q29:数组中出现次数超过一半的数字

就本题而言,个人觉得练习下partition函数是有必要的,毕竟它是快速排序的核心,是基础性的东西,也是必须要掌握的,至于书中给出的"取巧"性解法,是属于个人思维能力的考察,是一种考虑问题的思路,不是一两个问题就能练就的. partition函数,包括快速排序,是一定要信手拈来的,必须的. import random def MoreThanHalf(array): if len(array) == 0: return 0 start = 0 end = len(array) - 1

47. 数组中出现次数超过一半的数字[Number appears more than half times]

[题目]:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字. 例如长度为9的数组{1,2,3,2,2,2,5,4,2}中次数超过了数组长度的一半的数字为2,而长度为8的数组{1,2,3,2,2,2,5,4}则为非法输入. [思路一]:先对数组进行排序,再遍历排序后的数组,统计每个数的次数,出现次数最大的数即为要找的数. 时间复杂度:O(nlgn)+ O(n)= O(nlgn):空间复杂度:O(1). [思路二]:先对数组进行排序,出现次数超过数组长度的一半的数必然是数组中间的那个数.