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

思路:
解法一:基于partition函数的O(n)算法。
        先用partition函数对数组进行交换修改,然后对数组里的无效情况进行判断,还有计算通过partition计算出来的数字出现的次数是否超过一半。
解法二:数组中有一个数字出现的次数超过数组长度的一半,也就是说它出现的次数比其他所有数字出现次数的和还要多。因此我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字,一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1,;如果下一个数字和我们之前保存的数字不同,则次数减1,。如果次数为0,我们需要保存下一个数字,并把次数设为1.由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么要找的数字肯定是最后一次把次数设为1时对应的数字。
测试用例:
1)功能测试(输入的数组中存在一个出现次数超过数组长度一半的数字,输入的数组中不存在一个出现次数超过数组长度一半的数字);
2)特殊输入测试(输入的数组中只有一个数字、输入null指针)。
 
实现代码:
package com.yyq;
/*** Created by gao on 15-10-23.*/
public class MoreThanHalfNumber {public static boolean g_bInputInvalid = false;public static boolean checkInvalidArray(int[] numbers, int length) {g_bInputInvalid = false;if (numbers == null || length <= 0) {System.out.printf("Numbers is null! Invalid Parameters.");g_bInputInvalid = true;}return g_bInputInvalid;}public static boolean checkMoreThanHalf(int[] numbers, int length, int number) {int times = 0;for (int i = 0; i < length; i++) {if (number == numbers[i])times++;}boolean isMoreThanHalf = true;if (times * 2 <= length) {System.out.println("the number you find is not more than half.");isMoreThanHalf = false;g_bInputInvalid = true;}return isMoreThanHalf;}public static int Partition(int[] numbers, int length, int start, int end) {if (numbers == null || length <= 0 || start < 0 || end >= length) {System.out.printf("Invalid Parameters!");return -1;}int index = numbers[start];while (start < end) {while (start < end && numbers[end] >= index) end--;numbers[start] = numbers[end];while (start < end && numbers[start] <= index) start++;numbers[end] = numbers[start];}numbers[start] = index;return start;}//==================方法一:partition========================public static int moreThanHalfNum_solution1(int[] numbers, int length) {if (checkInvalidArray(numbers, length)) {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, start, end);}}int result = numbers[middle];if (!checkMoreThanHalf(numbers, length, result)) {result = 0;}return result;}public static int moreThanHalfNum_solution2(int[] numbers, int length) {if (checkInvalidArray(numbers, length)) {return 0;}int result = numbers[0];int times = 1;for(int i = 1; i < length; i++){if (times == 0){result = numbers[i];times = 1;}else if(numbers[i] == result){times ++;}else{times--;}}if (!checkMoreThanHalf(numbers, length, result)) {result = 0;}return result;}
// ====================测试代码====================public static void Test(String testName, int[] numbers, int length, int expectedValue, boolean expectedFlag){if(testName != null)System.out.println("\n"+testName+" begins: ");int[] copy = new int[length];for(int i = 0; i < length; ++i)copy[i] = numbers[i];System.out.printf("Test for solution1: ");int result = moreThanHalfNum_solution1(numbers, length);if(result == expectedValue && g_bInputInvalid == expectedFlag)System.out.println("Passed.");elseSystem.out.println("Failed.");System.out.printf("Test for solution2: ");result = moreThanHalfNum_solution2(copy, length);if(result == expectedValue && g_bInputInvalid == expectedFlag)System.out.println("Passed.");elseSystem.out.println("Failed.");copy = null;}// 存在出现次数超过数组长度一半的数字public static void Test1(){int numbers[] = {1, 2, 3, 2, 2, 2, 5, 4, 2};Test("Test1", numbers, numbers.length, 2, false);}// 不存在出现次数超过数组长度一半的数字public static void Test2(){int numbers[] = {1, 2, 3, 2, 4, 2, 5, 2, 3};Test("Test2", numbers, numbers.length, 0, true);}// 出现次数超过数组长度一半的数字都出现在数组的前半部分public static void Test3(){int numbers[] = {2, 2, 2, 2, 2, 1, 3, 4, 5};Test("Test3", numbers, numbers.length, 2, false);}// 出现次数超过数组长度一半的数字都出现在数组的后半部分public static void Test4(){int numbers[] = {1, 3, 4, 5, 2, 2, 2, 2, 2};Test("Test4", numbers, numbers.length, 2, false);}// 数组为1个元素public static void Test5(){int numbers[] = {1};Test("Test5", numbers, 1, 1, false);}// 输入空指针public static void Test6(){Test("Test6", null, 0, 0, true);}public static void main(String[] args){Test1();Test2();Test3();Test4();Test5();Test6();}
}

输出结果:
 
Test1 begins:
Test for solution1: Passed.
Test for solution2: Passed.
 
Test2 begins:
Test for solution1: the number you find is not more than half.
Passed.
Test for solution2: the number you find is not more than half.
Passed.
 
Test3 begins:
Test for solution1: Passed.
Test for solution2: Passed.
 
Test4 begins:
Test for solution1: Passed.
Test for solution2: Passed.
 
Test5 begins:
Test for solution1: Passed.
Test for solution2: Passed.
 
Test6 begins:
Test for solution1: Numbers is null! Invalid Parameters.Passed.
Test for solution2: Numbers is null! Invalid Parameters.Passed.
 
Process finished with exit code 0

 

转载于:https://www.cnblogs.com/yangyquin/p/4955437.html

P163、面试题29:数组中出现次数超过一半的数字相关推荐

  1. 剑指offer面试题[29]-数组中出现次数超过一半的数字

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

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

    题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [1, ...

  3. 【剑指offer-Java版】29数组中出现次数超过一半的数字

    数组中出现次数超过一半的数字 两种思路: 思路一:由于出现次数超过一半,所以如果对这个数组进行划分之后无论如何,位于数组下标 n/2的数字就是出现次数超过一半的数 所以问题就转换为了求划分一次之后 位 ...

  4. 剑指offer面试题39. 数组中出现次数超过一半的数字(数组)(摩尔投票法)

    题目描述 **数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素.** 思路 详见链接 代码 class Solution:def ...

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

    剑指offer--面试题29:数组中出现次数超过一半的数字 Solution1: 20180902日整理 注意几点: 1.若下一个数字和我们之前保存的数字相同,则次数 +1 2.若下一个数字和我们之前 ...

  6. 快速找出数组中出现次数超过一半的数字

    "只要不是特别大的内存开销,时间复杂度比较重要.因为改进时间复杂度对算法的要求更高." --吴斌(NVidia,Graphics Architect) 同样是查找,如果是顺序查找需 ...

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

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

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

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

  9. 《剑指offer》-- 复杂链表的复制、字符串的排列、数组中出现次数超过一半的数字、连续子数组的最大和

    一.复杂链表的复制: 参考牛客网的chancy:https://www.nowcoder.com/questionTerminal/f836b2c43afc4b35ad6adc41ec941dba 1 ...

  10. 数据结构与算法-- 数组中出现次数超过一半的数字(时间复杂度的讨论)

    时间效率 互联网想对时间效率格外的敏感,所以我们总是在需求迭代一定程度后去做优化.而且我们解决问题的时候,时间效率往往是一个考查的重点.因此我们平时编码过程中就必须不断的优化效率,追求完美的态度与能力 ...

最新文章

  1. 特斯拉AI总监用300行代码实现“迷你版GPT”,上线GitHub三天收获3.3k星
  2. 标签传播算法(Label Propagation)及Python实现
  3. 使用Docker-数据卷命令
  4. macos可以升级到指定版本吗_iOS14如期而至!重大更新的全新版本,值得升级吗?答案在这...
  5. linux查服务器总内存大小,在linux 下怎么查看服务器的cpu和内存的硬件信息
  6. “指向指针的指针”的作用和应用
  7. Spark 2.1.0集成CarbonData 1.1.0
  8. STM32单片机一个定时器输出不同频率PWM波
  9. 关于卸载流氓软件,自己试错的一些结论
  10. java毕业设计都市书城系统Mybatis+系统+数据库+调试部署
  11. 关于矩阵相乘顺序的理解(跟旋转没关)
  12. 流程图flow-chart 教程
  13. 人间炼狱,人性在哪儿---------------- 二十年穿铁衣取胆,母熊含泪杀子并自杀
  14. 网易2016实习研发笔试
  15. python正则表达式匹配字符串中的电话号码_Python正则表达式匹配字符串中的数字...
  16. 李德毅院士:迭代的智能——从薛定谔、图灵和维纳谈开去
  17. php打印出来乱码_PHP输出中文乱码怎么解决?
  18. 2.12父子进程通过匿名管道通信
  19. 物联网入门教程【上】
  20. 思迈特软件Smartbi:传统BI被“革命”,AI是BI技术未来的发展趋势

热门文章

  1. 移动端性能测试必备工具PerfDog性能狗
  2. BZOJ_4327_JSOI2012 玄武密码_AC自动机
  3. Cocos2d-x 游戏中子弹的设计
  4. 全球通史读书笔记上(第七章——战争的起源)
  5. Nature:鲍哲南团队研发新型可穿戴显示器,电子皮肤时代加速到来
  6. 普林斯顿大学算法公开课笔记
  7. 学计算机专业用什么u盘,介绍几款比较不错的U盘品牌-电脑自学网
  8. 我把自己的java库发布到了maven中央仓库,从此可以像Jackson、Spring的jar一样使用它了
  9. python查询ip归属地_基于Python的免费IP地址归属地查询
  10. JAVA 双亲委派机制