题目:输入一个数组,找出一个数字,它在数组中出现的次数超过数组的一半。

题目规定如果可以改变数组中元素的位置。

思路1:如果数组是排序的,那么中间元素的位置不就是次数超过数组一半的元素吗?是的,因此我们可以才用partition来做判断。如果partition的得到的整数index是在数组的中间,那么该元素就是超过数组中一半次数的元素。时间效率为O(n)。

题目规定不可以改变元素的位置

思路2:此时,我们不能对数据进行排序,因此,我们可以考虑到数组中出现次数超过一半的元素比其他所有的元素都出现的次数多,因此我们可以用一个记录数据出现次数的times来记录数组元素出现的次数。如果该元素出现times加一,如果下一个元素不是该元素,times减一。那么最后一个times设置为1的一定是超过数组一半次数的元素。

Java代码:思路1

import java.util.Random;

//允许改变数组中元素的位置,找到超过数组一半的元素。
public class HalfOfArrary {
//如果数组是排序的,找超过一半的数,就很好找,因此我们先来一个快排
public int partition(int[] a,int start,int end){
if(a==null)
return-1;
Random rand=new Random();
int index=start+rand.nextInt(end-start);
swrap(a,index,end);
int small=start-1;
for(index=start;index<end;index++){
if(a[index]<a[end]){
small++;
if(small!=index)
swrap(a,small,index);
}
}
small++;
swrap(a,small,end);
return small;
} public void swrap(int[] a, int index, int end) {
int temp=a[index];
a[index]=a[end];
a[end]=temp;
}
//查找超过一半的数,并返回
public int moreThanHalf(int[] a){
if(a==null)
return 0;
int start=0;
int len=a.length;
int middle=len>>1;
int end=len-1;
int index=partition(a,start,end);
while(index!=middle){
if(index>middle)
{
end=index-1;
index=partition(a,start,end);
}
else{
start=index+1;
index=partition(a,start,end);
}
}
int result=a[middle];
if(!(isMoreThanHalf(a,result))){
return 0;
}
return result; }
//判断数组中是否存在,超过一半的数
public boolean isMoreThanHalf(int[] a, int result) {
boolean isMoreHalf=true;
int time=0;
if(a==null)
return false;
for(int i=0;i<a.length;i++){
if(a[i]==result)
time++;
}
int middle=a.length>>1;
if(time>middle)
isMoreHalf=true;
return isMoreHalf; }
public static void main(String[] args){
int[] a={1,1,1,5,3,4,3,1,1,1,1};
HalfOfArrary hoa=new HalfOfArrary();
int result=hoa.moreThanHalf(a);
System.out.println(result+" ");
}
}

Java代码:思路2

//当规定不能改变数组中元素的位置的时候,找到大于数组中一半数的元素
public class MoreThanOfHalf {
public int moreThanHalfOfArray(int[] a){
if(a==null)
return 0;
int times=1;//标记数组中元素次数
int result=a[0];
for(int i=1;i<a.length;i++){
if(times==0){
result=a[i];
times=1;
}
else if(times==result)
times++;
else
times--;
}
if(!(isMoreThanHalf(a,result)))
result=0;
return result;
}
//判断数组中是否存在,超过一半的数
public boolean isMoreThanHalf(int[] a, int result) {
boolean isMoreHalf=true;
int time=0;
if(a==null)
return false;
for(int i=0;i<a.length;i++){
if(a[i]==result)
time++;
}
int middle=a.length>>1;
if(time>middle)
isMoreHalf=true;
return isMoreHalf; }
public static void main(String[] args){
int[] a={1,2,3,3,4,3,4,3,3,3};
MoreThanOfHalf mh=new MoreThanOfHalf();
int result=mh.moreThanHalfOfArray(a);
System.out.println(result+"");
}
}

剑指offer-第五章优化时间和空间效率(数组中出现次数超过一半的数字)的更多相关文章

  1. 剑指Offer面试题29(java版):数组中出现次数超过一半的数字

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

  2. 剑指offer-第五章优化时间和空间效率(从1到n的整数中1出现的次数)

    题目:输入一个整数n,从1到n这n个十进制整数中1出现的次数. 思路1:对1到n中的任意一个数i对其进行求余数来判断个位是否为1,然后再求除数,判断十位是否为1.统计出1的个数.然后对1到n用一个循环 ...

  3. 剑指offer-第五章优化时间和空间效率(数组中的逆序对的总数)

    题目:在数组中如果两个数字的前面的数比后面的数大,则称为一对逆序对.输入一个数组求出数组中逆序对的总数. 以空间换时间:思路:借助一个辅助数组,将原来的数组复制到该数组中.然后将该数组分成子数组,然后 ...

  4. 剑指offer-第五章优化时间和空间效率(把数组排列成最小的数)

    题目:输入一个正整数数组,将所有的数,排列起来,组成一个最小的数.

  5. 剑指offer-第五章优化时间和空间效率(两个链表的第一个公共节点)

    思路1:要求的是两个链表的第一个公共节点,首先想到的是用栈来存放两个链表,然后依次从栈中抛出,直到最后一个相同的节点为止.但是要用到两个栈,空间复杂度为O(n): 思路2:从头到尾分别遍历两个链表得到 ...

  6. 剑指offer-第五章优化时间和空间效率(在字符串中第一次出现切只出现一次的字符)

    题目:在字符串中第一次出现切只出现一次的字符 思路:用HashMap来存放对应的char值和该char出现的次数.做一次变量就可以得到第一个只出现一次的字符. Java代码: import java. ...

  7. 剑指offer-第五章优化时间和空间效率(连续子数组的最大和)

    题目:输入一个数组,数组中有正也有负,数组中连续的一个或者连续的多个数字组成一个子数组.求所有的子数组和的最大值.要求时间复杂度为O(n) 思路:我们的最直观的想法就是求出这个数组中的所有的子数组,然 ...

  8. 剑指offer-第五章优化时间和空间效率(最小的k个数)

    题目:输入n个数,输出最小的k个数. 时间复杂度为O(n) 思路1:我们想的到的最直接的思路就是对这个N个数进行排序,然后就可以找到最小的k个了,同样可以用快排partition.但是只要找到前K个最 ...

  9. 剑指offer第五章

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

随机推荐

  1. function func(){} 与 var func=function(){}的区别

    1  var func =function(){}  ,即和 var 变量的特性 一样. func 变量名提前,但是不会初始化,直到执行到初始化代码. 2  function func(){}     ...

  2. Idea中解决Git中pull代码内容冲突

    Git开发中,由于项目开发人员不只一个,所以在代码开发中,多个开发人员可能会对同一文件同一地方的代码进行修改,这样在先后提交到master上时,就会产生冲突,以下是演示冲突产生和解决冲突的示例: 1. ...

  3. SSD: Single Shot MultiBox Detector 编译方法总结

    SSD是一个基于单网络的目标检测框架,它是基于caffe实现的,所以下面的教程是基于已经编译好的caffe进行编译的. caffe的编译可以参考官网 caffe Installation Instal ...

  4. linux ioctl()函数

    我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. ...

  5. docker 跨主机网络:overlay 简介

    简介 docker 在早前的时候没有考虑跨主机的容器通信,这个特性直到 docker 1.9 才出现.在此之前,如果希望位于不同主机的容器能够通信,一般有几种方法: 使用端口映射:直接把容器的服务端口 ...

  6. 通过使用Netty实现RPC

    目标:通过使用Netty框架实现RPC(远程过程调用协议),技术储备为以后实现分布式服务框架做技术储备.在这里实现自定义协议主要实现远程方法调用. 技术分析: 1.通过Java的反射技术我们可以获取对 ...

  7. 阿里云上如何利用yum安装jenkins

    一. 安装jdk 确保安装jenkins前jdk已经安装,如何安装见<如何在阿里云上部署war包到tomcat服务器> 二. 安装jenkins 使用以下命令安装jenkins: wget ...

  8. Tavas and Karafs 二分+结论

    二分比较容易想到 #include<map> #include<set> #include<cmath> #include<queue> #includ ...

  9. 【总结】对异步处理的http接口进行性能测试

    以前对接口做性能测试,接口都是同步处理的,请求之后等待响应结果就知道处理结果了,这样只要看这个接口是否异常,如果无异常无报错记录这个接口的响应时间.TPS等性能指标进行分析就可以了,最近在工作中遇到了 ...

  10. 51nod 1270 dp

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1270 简单的线性dp,最近狂刷水题真的是...药丸 差值最大得话要么是峰 ...