题目描述

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

牛客网刷题地址

思路分析

  有两种思路:

  1. 快速排序的思想:数字次数超过一半,可以说明排序之后中间的数字一定是所求的数字,即统计学上的中位数,利用partition函数求得某一下标,如果改下标正好为n/2,则该数字为所求数字,需要检查该数字在数组中出现的次数;如果 < n/2,则中位数位于改下标右边,如果 > n/2 则位于左边;
  2. 统计数字出现的次数,首先先保存一个哨兵数字和一个计数器,遍历数组后面的数字,遇到与该数字相同的则计数器+1,遇到不同的-1,如果计数器减为0时,就重新保存一个数字,重新开始从1开始计数。到最后计数器如果>0,判断该数字出现次数。

测试用例

  1. 功能测试:输入的数组中存在一个出现次数超过数组长度一半的数字:输入的数组中不存在一个出现次数超过数组长度一半的数字。
  2. 特殊输入测试:输入的数组中只有一个数字;输入nullptr 指针。

Java代码

public class Offer39 {
public static void main(String[] args) {
test1();
test2();
test3(); } public static int MoreThanHalfNum_Solution(int[] array) {
return Solution1(array);
} /**
* partition方法
*
* @param array
* @return
*/
private static int Solution1(int[] array) {
if (array == null || array.length == 0) {
return 0;
}
int middle = array.length >> 1;
int low = 0;
int high = array.length - 1;
int index = partition(array, low, high);
while (index != middle) {
if (index < middle) {
low = index + 1;
index = partition(array, low, high);
} else {
high = index - 1;
index = partition(array, low, high);
}
} int result = array[middle];
int times = 0;
for (int i = 0; i < array.length; i++) {
if (result == array[i]) {
times++;
}
} if (times * 2 > array.length) {
return result;
}
return 0;
} private static int partition(int[] array, int low, int high) {
int privot = array[low];
while(low<high){
while(low<high && array[high]>=privot) high--;
array[low] = array[high];
while(low<high && array[low]<=privot) low++;
array[high] = array[low];
}
array[low] = privot;
return low;
} private static int Solution2(int[] array) {
if (array == null || array.length == 0) {
return 0;
}
int count = 1;
int flagNum = array[0];
for (int i = 1; i < array.length; i++) {
if (count == 0) {
flagNum = array[i];
count = 1;
} else if (array[i] == flagNum) {
count++;
} else {
count--;
}
}
if (count > 0) {
int times = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == flagNum) {
times++;
}
}
if (times * 2 > array.length) {
return flagNum;
}
}
return 0;
} private static void test1() {
int[] array = { 1, 2, 3, 2, 2, 2, 5, 4, 2 };
int result = MoreThanHalfNum_Solution(array);
System.out.println(result);
} private static void test2() {
int[] array = { 1 };
int result = MoreThanHalfNum_Solution(array);
System.out.println(result);
} private static void test3() {
int[] array = {};
int result = MoreThanHalfNum_Solution(array);
System.out.println(result);
}
}

代码链接

剑指Offer代码-Java

【Offer】[39] 【数组中出现次数超过一半的数字】的更多相关文章

  1. 剑指 Offer 39. 数组中出现次数超过一半的数字 + 摩尔投票法

    剑指 Offer 39. 数组中出现次数超过一半的数字 Offer_39 题目描述 方法一:使用map存储数字出现的次数 public class Offer_39 { public int majo ...

  2. 剑指 Offer 39. 数组中出现次数超过一半的数字

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

  3. 力扣 - 剑指 Offer 39. 数组中出现次数超过一半的数字

    题目 剑指 Offer 39. 数组中出现次数超过一半的数字 思路1(排序) 因为题目说一定会存在超过数组长度一半的一个数字,所以我们将数组排序后,位于length/2位置的一定是众数 代码 clas ...

  4. 【Java】 剑指offer(39) 数组中出现次数超过一半的数字

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如 ...

  5. 每日一题 - 剑指 Offer 39. 数组中出现次数超过一半的数字

    题目信息 时间: 2019-06-29 题目链接:Leetcode tag: 数组 哈希表 难易程度:简单 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 假设数组是非空的 ...

  6. 剑指Offer:数组中出现次数超过一半的数字【39】

    剑指Offer:数组中出现次数超过一半的数字[39] 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于这 ...

  7. 【剑指Offer】数组中出现次数超过一半的数字 解题报告(Python)

    [剑指Offer]数组中出现次数超过一半的数字 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-inter ...

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

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

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

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

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

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

随机推荐

  1. 【原创】JAVA进程突然消失的原因?

    引言 值此七夕佳节,烟哥放弃了无数妹纸的邀约,坐在电脑面前码字,就是为了给读者带来新的知识,这是一件伟大的事业! 好吧,实际情况是没人约.为了化解尴尬,我决定卖力写文章,嗯,一定是我过于屌丝! 好了, ...

  2. what is the CCA?

    Clear Channel Assessment (CCA) is one of two carrier sense mechanisms in WLAN (or WiFi). It is defin ...

  3. Java并发编程实战笔记—— 并发编程1

    1.如何创建并运行java线程 创建一个线程可以继承java的Thread类,或者实现Runnabe接口. public class thread { static class MyThread1 e ...

  4. forward(转发)和redirect(重定向)的区别

    在学习Servlet和JSP时,经常会使用到forward和redirect,我们先来看这两者在Servlet中的调用方式: 1.forward request.getRequestDispatche ...

  5. gin+vue的前后端分离开源项目

    该项目是gin+vue的前后端分离项目,使用gorm访问MySQL,其中vue前端是使用vue-element-admin框架简单实现的: go后台使用jwt,对API接口进行权限控制.此外,Web页 ...

  6. 既然synchronized是"万能"的,为什么还需要volatile呢?

    在我的博客和公众号中,发表过很多篇关于并发编程的文章,之前的文章中我们介绍过了两个在Java并发编程中比较重要的两个关键字:synchronized和volatile 我们简单回顾一下相关内容: 1. ...

  7. 在Docker for Windows中运行GUI程序

    Docker运行GUI原理 Docker目前大多应用在服务器领域,那么在Docker中可以运行GUI程序吗?怀着好奇心google了一番,还真有人写了一篇文章 running-gui-applicat ...

  8. python相关,各种命令集合

    PS: cmd必须管理员身份运行 python版本 2.7  可能会出现编码问题:在 Lib/site-packages 新建文件 sitecustomize.py import sys  sys.s ...

  9. JVM调优实战:G1中的to-space exhausted问题

    最近刚刚将自己的一个应用从CMS升级到G1,在一天早上,刚刚到办公室坐下,就收到手机一阵报警,去查看了监控,发现机器的内存出现了一个90度的涨幅,如下图所示: 在查看GC日志后,发现那个时间点附近出现 ...

  10. 编程题及解题思路(1,String)

    题目描述 请实现一个算法,确定一个字符串的所有字符是否全都不同.这里我们要求不允许使用额外的存储结构. 给定一个string iniString,请返回一个bool值,True代表所有字符全都不同,F ...