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

数组中出现次数超过一半的数字 代码(C)

本文地址: http://blog.csdn.net/caroline_wendy

题目: 数组中有一个数字出现的次数超过数组长度的一半, 请找出这个数字.

1. 使用高速排序(QuickSort)的方法, 把中值(middle)和索引(index)匹配, 输出中值, 并检測是否符合要求.

2. 使用计数方法依次比較.

代码: 

方法1:

/*
 * main.cpp
 *
 *  Created on: 2014.6.12
 *      Author: Spike
 */

/*eclipse cdt, gcc 4.8.1*/

#include <stdio.h>
#include <stdlib.h>

int RandomInRange(int min, int max)
{
    int random = rand() % (max - min + 1) + min;
    return random;
}

void Swap(int* num1, int* num2)
{
    int temp = *num1;
    *num1 = *num2;
    *num2 = temp;
}

int Partition(int data[], int length, int start, int end)
{
    if(data == NULL || length <= 0 || start < 0 || end >= length) {
    	return -1;
    }

    int index = RandomInRange(start, end);
    Swap(&data[index], &data[end]);

    int small = start - 1;
    for(index = start; index < end; ++ index)
    {
        if(data[index] < data[end])
        {
            ++ small;
            if(small != index)
                Swap(&data[index], &data[small]);
        }
    }

    ++ small;
    Swap(&data[small], &data[end]);

    return small;
}

bool CheckMoreThanHalf (int* numbers, int length, int number)
{
	int times = 0;
	for (int i=0; i<length; ++i) {
		if (numbers[i] == number)
			++times;
	}
	if (times*2 <= length) {
		return false;
	}

	return true;
}

int MoreThanHalfNum(int* numbers, int length) {
	if (numbers == NULL || length <= 0)
		return 0;

	int middle = length >> 1;
	int start = 0;
	int end = length-1;
	int index = Partition(numbers, length, start, end);
	while (index != middle) {
		if (index > middle) { //前面部分的数字多
			end = index-1;
			index = Partition(numbers, length, start, end);
		} else {
			start = index+1;
			index = Partition(numbers, length, index+1, start);
		}
	}

	int result = numbers[middle];
	if (!CheckMoreThanHalf(numbers, length, result))
		return 0;

	return result;
}

int main(void)
{
    int str[] =  {1, 2, 3, 4, 4, 4, 5, 4, 4};
    int result = MoreThanHalfNum(str, 9);
    printf("reuslt = %d\n", result);

    return 0;
}

方法2:

/*
 * main.cpp
 *
 *  Created on: 2014.6.12
 *      Author: Spike
 */

/*eclipse cdt, gcc 4.8.1*/

#include <stdio.h>
#include <stdlib.h>

bool CheckMoreThanHalf (int* numbers, int length, int number) {
	int times = 0;
	for (int i=0; i<length; ++i) {
		if (numbers[i] == number)
			times++;
	}
	if (times*2 < length)
		return false;
	return true;
}

int MoreThanHalfNum (int* numbers, int length) {
	if (numbers == NULL || length <= 0)
		return 0;
	int result = numbers[0];
	int times = 1;
	for (int i=0; i<length; ++i) {
		if (times == 0) {
			result = numbers[i];
			times = 1;
		}
		if (numbers[i] == result) times++;
		else times--;
	}
	if (!CheckMoreThanHalf(numbers, length, result))
		return 0;
	return result;
}

int main(void)
{
    int str[] =  {1, 2, 3, 2, 2, 2, 5, 2, 4};
    int result = MoreThanHalfNum(str, 9);
    printf("reuslt = %d\n", result);

    return 0;
}

输出:

reuslt = 4

时间: 2024-10-19 06:18:11

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

[算法]数组中出现次数超过一半的数字

题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如果不存在则输出0. 思路 这道题最简单的思路就是排序,然后统计每个数字出现的次数,这样时间复杂度是O(nlogn). 也可以用哈希表进行次数的统计,但是这样最大的空间复杂度是O(n). 这里提供一种时间复杂度是O(n),空间复杂度是O(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). [思路二]:先对数组进行排序,出现次数超过数组长度的一半的数必然是数组中间的那个数.

剑指OFFER之数组中出现次数超过一半的数字(九度OJ1370)

题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 输入: 每个测试案例包括2行: 第一行输入一个整数n(1<=n<=100000),表示数组中元素的个数. 第二行输入n个整数,表示数组中的每个元素,这n个整数的范围是[1,1000000000]. 输出: 对应每个测试案例,输出出现的次数超过数组长度的一半的数,如果没有输出-1. 样例输入:

25.数组中出现次数超过一半的数字

数组中出现次数超过一半的数字 参与人数:3419时间限制:1秒空间限制:32768K 本题知识点: 数组 算法知识视频讲解 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如果不存在则输出0. 这道题很简单,可是我却做了很久,中间想到了用multimap记录键值对(以数组的元素做键,元素出现的次数做值),然后合并键,可是multimap好像没有这

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

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

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

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

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

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

数据结构-数组中出现次数超过一半的数字

题目:数字中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 分析:首先进行排序,因为大于一半,所以说经过排序之后的数组,如有次数大于的话说明那个数肯定是数组中间的那个数. #include <iostream> using namespace std; void QickSort(int *a,int n,int low,int high){ int i=l

【剑指offer】十九,数组中出现次数超过一半的数字

题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 分析:找数组中出现次数超过一半的数字,我们一半可以采用两种方法,一是使用快排,对数组进行排序,然后直接输出排序数组中间位置的数.第二种是使用HashMap<Integer,Integer>,key是数组中的数字,value为其在数组中出现的次数,顺序扫描数组,记录下数组出现的次数,输出大于数组长