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


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

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

    思路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+"");
        	}
        }
    
  • 相关阅读:
    WPF自定义控件
    NPOI设置Excel单元格字体、边框、对齐、背景色
    关于StreamReader.ReadToEnd方法
    ASP.NET Core Web多语言项目
    docker与虚拟机的区别
    C# Task.Run 和 Task.Factory.StartNew 区别
    MVC的SignalR例子
    深圳游玩攻略
    一个域名下多个Vue项目
    Linq的执行效率及优化
  • 原文地址:https://www.cnblogs.com/hupp/p/4749946.html
Copyright © 2020-2023  润新知