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

题目描述

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

解法一:基于Partition函数时间复杂度为O(n)的算法

简要思路

  数组中有一个数字出现的次数超过了数组长度的一半。如果把这个数组排序,那么排序之后位于数组中间的数字一定就是那个出现次数超过数组长度一半的数字。也就是说,这个数字就是统计学上的中位数。

  在随机快排算法中,我们现在数组中随机选择一个数字,然后调整数组中数字的顺序,使得比选中的数字小的数字都在它的左边,比选中数字大的数字都排在它的右边。如果选中的这个数字的小标刚好是n/2,那么这个数字就是这个数字的中位数;如果它的下标大于n/2,那么中位数应该位于它的左边,我们可以接着在它的左边部分的数组中进行查找。否则,可以在右边中进行查找!

  大概意思是这样的:

Java实现代码

import java.util.Scanner;

public class PartitionDemo {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str = input.nextLine();
String[] arrStr =str.split(" ");
int[] arrN = new int[arrStr.length];
for(int i=0;i<arrStr.length;i++)
arrN[i]= Integer.parseInt(arrStr[i]);
System.out.println(MoreThanHalfNum(arrN,arrN.length));
}
//数目超过一半的数字
public static int MoreThanHalfNum(int[] numbers,int length)
{
int middle = length>>1;
int start = 0;
int end = length-1;
int index = partition(numbers,start,end);
while (index!=middle)
{
if(index>middle) {
end = index-1;
index = partition(numbers,start,end);
}
else{
start = index+1;
index=partition(numbers,start,end);
}
}
int result = numbers[middle];
return result;
}
//划分
public static int partition(int[] aux,int lo,int hi)
{
int i=lo,j=hi+1; //左右两个指针,分别从两端开始
int val = aux[lo]; //取最左边的第一个元素为枢纽元素
while (true)
{
while (aux[++i]<val)if(i==hi)break; //左指针向右找到一个大于枢纽的
while (aux[--j]>val)if(j==lo)break; //右指针向左找到一个大于枢纽的 if(i>=j) break; //这个i>=j是很关键的,这表明现在已经划分成功,即两边元素有序!
exch(aux,i,j); //i!=j,表示还有能找的!
}
exch(aux,lo,j); //把枢纽元素交换至它应该的位置!
return j; //把划分点返回区,目的是说,从这里开始,两边分别已成为为左右子序列,返回的是j这是很关键的,因为i可能大于j。
}
//交换
public static void exch(int[] aux,int i,int j)
{
int t=aux[i];
aux[i]=aux[j];
aux[j]=t;
}
}

  

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

  1. python剑指offer数组中出现次数超过一半的数字

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

  2. 剑指Offer——数组中出现次数超过一半的数字——一题多解

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

  3. 剑指offer——数组中出现次数超过一半的数字(c++)

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

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

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

  5. 用js刷剑指offer(数组中出现次数超过一半的数字)

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

  6. 剑指Offer-28.数组中出现次数超过一半的数字(C++/Java)

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

  7. 剑指offer--11.数组中出现次数超过一半的数字

    unique(), count()函数好用 ---------------------------------------------------------------------- 时间限制:1秒 ...

  8. 1-剑指offer: 数组中出现次数超过一半的数字

    题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为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. Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)

    剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...

随机推荐

  1. Mac环境下svn命令行的使用

    在Windows环境中,我们一般使用TortoiseSVN来搭建svn环境.在Mac环境下,由于Mac自带了svn的服务器端和客户端功能,所以我们可以在不装任何第三方软件的前提下使用svn功能,不过还 ...

  2. Android 监听双卡信号强度(附完整代码)

    Android 监听双卡信号强度 监听单卡信号强度 监听单卡的信号强度非常简单直接用TelephonyManager.listen()去监听sim卡的信号强度. TelephonyManager = ...

  3. dedecms调用新闻文章列表

    效果如下: 代码如下: <div class="list"> <ul class="d6 ico4"> {dede:list pages ...

  4. 终于会用c#中的delegate(委托)和event(事件)了 [转]

    原文 : http://www.cnblogs.com/zhangchenliang/archive/2012/09/19/2694430.html 一.开篇忏悔 对自己最拿手的编程语言C#,我想对你 ...

  5. 获取安装后Apache、MySQL、Nginx、PHP编译时参数

    # cat /usr/local/apache2/build/config.nice      //获取Apache编译时的参数 #!/bin/sh # #Created by configure & ...

  6. eclipse离线安装插件过程

    离线安装插件: 1. help -> install New Softe.. 2. 打开安装插件界面 最后点击,next, 同意事项,重启eclipse.

  7. Linux程序

    1.如何找到一个进程的安装程序目录与启动目录 2.如何完全卸载一个程序

  8. Oracle 查询一个表的所有字段

    select * from user_tab_columns where table_name = 'T_B_CLIENT_MSG'

  9. Android · PendingIntent学习

    Intent 是及时启动,intent 随所在的activity 消失而消失 PendingIntent用于处理即将发生的事情.比如在通知Notification中用于跳转页面,但不是马上跳转.   ...

  10. Excel工作表忘记密码如何破解?

    第一种方法就是按住快捷键ALT+F11,然后切换出VBA编辑窗口,如图一:在该窗口的左侧我们的选择那个忘记密码的工作表,比如sheet 1... 2 然后我们复制以下代码 “Sub Pojie()Ac ...