【Offer】[39] 【数组中出现次数超过一半的数字】
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
思路分析
有两种思路:
- 快速排序的思想:数字次数超过一半,可以说明排序之后中间的数字一定是所求的数字,即统计学上的中位数,利用partition函数求得某一下标,如果改下标正好为n/2,则该数字为所求数字,需要检查该数字在数组中出现的次数;如果 < n/2,则中位数位于改下标右边,如果 > n/2 则位于左边;
- 统计数字出现的次数,首先先保存一个哨兵数字和一个计数器,遍历数组后面的数字,遇到与该数字相同的则计数器+1,遇到不同的-1,如果计数器减为0时,就重新保存一个数字,重新开始从1开始计数。到最后计数器如果>0,判断该数字出现次数。
测试用例
- 功能测试:输入的数组中存在一个出现次数超过数组长度一半的数字:输入的数组中不存在一个出现次数超过数组长度一半的数字。
- 特殊输入测试:输入的数组中只有一个数字;输入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】[39] 【数组中出现次数超过一半的数字】的更多相关文章
- 剑指 Offer 39. 数组中出现次数超过一半的数字 + 摩尔投票法
剑指 Offer 39. 数组中出现次数超过一半的数字 Offer_39 题目描述 方法一:使用map存储数字出现的次数 public class Offer_39 { public int majo ...
- 剑指 Offer 39. 数组中出现次数超过一半的数字
剑指 Offer 39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [ ...
- 力扣 - 剑指 Offer 39. 数组中出现次数超过一半的数字
题目 剑指 Offer 39. 数组中出现次数超过一半的数字 思路1(排序) 因为题目说一定会存在超过数组长度一半的一个数字,所以我们将数组排序后,位于length/2位置的一定是众数 代码 clas ...
- 【Java】 剑指offer(39) 数组中出现次数超过一半的数字
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如 ...
- 每日一题 - 剑指 Offer 39. 数组中出现次数超过一半的数字
题目信息 时间: 2019-06-29 题目链接:Leetcode tag: 数组 哈希表 难易程度:简单 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 假设数组是非空的 ...
- 剑指Offer:数组中出现次数超过一半的数字【39】
剑指Offer:数组中出现次数超过一半的数字[39] 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于这 ...
- 【剑指Offer】数组中出现次数超过一半的数字 解题报告(Python)
[剑指Offer]数组中出现次数超过一半的数字 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-inter ...
- 剑指OFFER之数组中出现次数超过一半的数字(九度OJ1370)
题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2 ...
- 《剑指offer》-数组中出现次数超过一半的数字
/* 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如果 ...
- 【剑指offer】数组中出现次数超过一半的数字
一.题目: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2 ...
随机推荐
- JVM和GC的工作原理
转载于https://uestc-dpz.github.io JVM Java 虚拟机 Java 虚拟机(Java virtual machine,JVM)是运行 Java 程序必不可少的机制.JVM ...
- 【Java例题】8.1手工编写加法器的可视化程序
1. 手工编写加法器的可视化程序. 一个Frame窗体容器,布局为null,三个TextField组件,一个Button组件. Button组件上添加ActionEvent事件监听器ActionLis ...
- elk系列教程:docker中安装配置elk
elasticSearch Docker安装elasticsearch: docker pull docker.io/elasticsearch:7.2.0 启动: docker run -p 920 ...
- 科普向 + 折腾向 ——你了解磁盘、分区、文件系统、GPT、UEFI吗?在笔记本上安装五个系统是怎样的体验?
[Windows 7 + Windows 8 (PE) + Windows 10 + deepin-Linux + MacOS X] 前言:随着软硬件技术的发展UEFI引导逐渐取代传统BIOS引导,最 ...
- viewpager_轮播
public class MainActivity extends Activity { private ViewPager pager; private int[] id={R.layout.lay ...
- Cocos Creator经典游戏制作之:信使(The Messenger)
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- Joda Time使用小结
一.Joda Time基础操作 1. 构造指定时间 // 明确给出年月日时分秒,同时还可以指定毫秒 DateTime dateTime = new DateTime(2017,9,14,20,30,0 ...
- Hive 窗口分析函数
1.窗口函数 1.LAG(col,n,DEFAULT) 用于统计窗口内往上第n行值 第一个参数为列名,第二个参数为往上第n行(可选,默认为1),第三个参数为默认值(当往上第n行为NULL时候,取默认值 ...
- c++的构造和析构
//文件名ss.h 1 #pragma once class ss { private: char*p;//利用指针来为p申请对内存 float height; ; char sex; public: ...
- @Validated和@Valid区别
注解地方 @Validated:可以用在类型.方法和方法参数上.但是不能用在成员属性(字段)上 @Valid:可以用在方法.构造函数.方法参数和成员属性(字段)上 两者是否能用于成员属性(字段)上直接 ...