zoukankan      html  css  js  c++  java
  • 超过一半的数字

    题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。

    思路:解法一、排序完后返回arr[N/2] O(nlgn) Arrays.sort(arr); System.out.println(arr[N/2]);
        解法二、hash统计
        解法三、顺序统计,就跟寻找乱序数组中第K大的数解法一样。O(N),那么这里就是求乱序数组中第N/2大的数,限制:需要改动数组的内容
        解法四、不同的数,进行消除

    代码:

    public class MoreThanHalf {
    
    	public static void main(String[] args) {
    		
    		f(new int[]{5,6,6,6,2,3,6});
    
    	}
    	
    	// 不同的数,进行消除,O(N)
    	public static void f(int arr[]){
    		//候选数  先定位第一个元素
    		int candidate = arr[0];
    		// 出现的次数
    		int nTimes = 1;
    		// 扫描数组
    		for (int i = 1; i < arr.length; i++) {
    			// 两两消减为0,应该把现在的元素作为候选值
    			if (nTimes==0 ) {
    				candidate = arr[i];
    				nTimes = 1;
    				continue;
    			}
    			// 如果遇到和候选值相同的,次数加一
    			if (arr[i]==candidate) {
    				nTimes++;
    				// 不同的数,进行消减
    			}else {
    				nTimes--;
    			}
    		}
    		//System.out.println(nTimes);
    		if (nTimes==0) {
    			System.out.println(-1);
    		}else {
    			System.out.println(candidate);
    		}
    		
    	}
    
    }
    

    结果:

      

    趣味拓展:加强版水王问题,假如出现的次数恰好为个数的一般,求出这个数。

    思路:有个巧妙的方法扫描一遍数组就解决问题,水王发的贴子占总数的一半,说明总数为偶数;不失一般性,假设隔一个数就是水王的id,两两不同最后一定会消减为0,如果水王是最后一个元素,那么每次扫描的时候,多一个动作,和最后一个元素做比较,单独计数,计数恰好一半。如果不是,那么去掉最后一个元素,水王就是留下的那么candidate。

    代码:

    public class MoreThanHalf {
    
    	public static void main(String[] args) {
    		//进行测试数据要满足测试条件 不然结果会错误
    		f(new int[]{6,6,6,5,6,1,2,3,4,6});
    
    	}
    	
    	// 不同的数,进行消除,O(N)
    	public static void f(int arr[]){
    		//候选数  先定位第一个元素
    		int candidate = arr[0];
    		// 出现的次数
    		int nTimes = 1;
    		int countOfLast = 1;  // 统计这个元素出现的次数
    		// 扫描数组
    		for (int i = 1; i < arr.length; i++) {
    			if (arr[i-1]==arr[arr.length-1]) {
    				countOfLast++;
    			}
    			// 两两消减为0,应该把现在的元素作为候选值
    			if (nTimes==0 ) {
    				candidate = arr[i];
    				nTimes = 1;
    				continue;
    			}
    			// 如果遇到和候选值相同的,次数加一
    			if (arr[i]==candidate) {
    				nTimes++;
    				// 不同的数,进行消减
    			}else {
    				nTimes--;
    			}
    		}
    		//System.out.println(nTimes);
    		if (countOfLast==arr.length/2) {
    			System.out.println(arr[arr.length-1]);
    		}else {
    			System.out.println(candidate);
    		}
    		
    	}
    
    }

    结果:

      

  • 相关阅读:
    【WPF】实现QQ中的分组面板
    [WPF Bug清单]之(11)——错位的RenderTransform动画
    【JavaWeb项目】一个简洁完整的论坛项目(暑假答辩作品)
    【C语言】Oj题目常见问题如何处理文件尾
    【Java】寒假答辩作品:Java小游戏
    【C语言】用c语言实现一些简单的算法可视化(个人代码分享)
    2020蓝桥杯C++B组省赛第二场个人感受和个人题解
    【C语言】分享一些个人C语言程序代码[大一上集合]
    【C语言】分享一些个人C语言程序代码[大一下集合]
    【C语言】从零开始的C语言小游戏之路(总)
  • 原文地址:https://www.cnblogs.com/xiaoyh/p/10273429.html
Copyright © 2011-2022 走看看