找出数组中出现次数大于n/2、n/3,n/k的数

1.找出数组中次数大于n/2的元素
说明:算法空间复杂度o(n),时间复杂度o(1)
数组中次数超过n/2的数最多1个,设置一个频率数,前一个数和后一个数相同,频率+1,
否则-1,只要有数频率超过数组长度一半,最终这个频率肯定大于0.

public static int solve2(int [] array) {
    	if(array == null || array.length == 0) return -1;
    	int temp = array[0],time = 0;
    	for(int i= 0;i<array.length;i++) {
    		if(array[i] == temp) time++;
    		else if(time <=0) {
    			temp = array[i];
    			time = 0;
    		}else {
    			time --;
    		}
    	}
    	 time = 0;
    	for(int i = 0;i<array.length;i++) {
    		if(temp == array[i]) time++;
    	}
    	if(time>array.length/2) return temp;
    	return -1;
    }

2.找出数组中出现次数超过n/3的数
超过n/2的数,最多2个,可以设置两个临时变量保存数组元素,两个频率变量

public static ArrayList solve(int [] array) {
    ArrayList<Integer> list = new ArrayList<Integer>();
    if(array == null ||array.length == 0) return null;
    int maj1 = array[0],maj2 = array[0];
    int count1 = 0,count2 = 0;
    int len = array.length;
    for(int i = 0;i<len;i++) {
    	if(array[i] == maj1) count1++;
    	else if(array[i] == maj2) count2++;
    	else if(count1<=0) {
    		count1 = 1;
    		maj1 = array[i];
    	}else if(count2<=0) {
    		count2 = 1;
    		maj2 = array[i];
    	}else {
    		--count1;
    		--count2;
    	}
    }
    count1 = count2 =0;
    for(int i =0;i<len;i++) {
    	if(array[i] == maj1) count1++;
    	if(array[i] == maj2) count2++;
    }
    if(count1>len/3) list.add(maj1);
    if(count2>len/3) list.add(maj2);
    return list;
    }

3.找出数组个数大于n/k的
大于n/k的最多也就是k-1个,所以map集合每当满k-1个的时候,如果,前后不相等,集合内所有的元素个数都要-1,为0的清除掉。

public static void solve3(int [] arr,int k) {
    	Map<Integer,Integer> map = new HashMap<>();
    	//首先找到k-1个不同的数,并记录他们出现的次数,继续向后遍历
    	//若下一个数map里有则将该数个数即value+1,否则map里数的个数都减1
    	//否则加入该数,次数记为1
    	for(int anArr:arr) {
    	 Integer value;
    	 if((value = map.get(anArr))!=null) {
    		 map.replace(anArr, value+1);
    	 }else {
    		 if(map.size() == k-1) {
    			 subtrackAll(map,k);
    		 }else {
    			 map.put(anArr,1);
    		 }
    	 }
      }
     //将map里所有数的个数即value都清0,因为map中的数并非都符合要求
    	map.keySet().forEach(integer->map.replace(integer, 0));
     //再次循环统计map里数字的真正个数
    	for(int num:arr) {
    		Integer val;
    		if((val = map.get(num))!= null) {
    			map.replace(num, val+1);
    		}
    	}
    	map.forEach((key,value)->{
    		if(value>arr.length/k) {
    			System.out.println(key+" ");
    		}
    	});
    }
	private static void subtrackAll(Map<Integer, Integer> map, int k) {
		List<Integer> list = new ArrayList();
	// 将map里全部数字的value值减1,减1后若value==0,则删除该键
		map.forEach((integer,integer2)->{
			if(integer2 == 1) {
				list.add(integer);
			}else map.replace(integer, integer2-1);
		});
		if(list.size()!=0) {
			for(Integer key:list) {
				map.remove(key);
			}
		}	
	}  

为什么最后还要验证一下,例如找大于n/2的数,数组为 2 2 2 3 3 3 最终temp为3但是显然3个数并没有大于n/2

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第一篇 面试题 ................................................................................ 8 1.1. 简介 ............................................................................................................... 8 1.2. 面试题集合(一) .......................................................................................... 8 1.2.1. 把二元查找树转变成排序的双向链表.................................................... 8 1.2.2. 下排每个都是先前上排那十个在下排出现次数 ..........................11 1.2.3. 设计包含 min 函的栈 ...................................................................... 14 1.2.4. 求子数组的最大和.............................................................................. 20 1.2.5. 在二元树中找出和为某一值的所有路径 .............................................. 22 1.2.6. Top K 算法详细解析---百度面试 ......................................................... 29 1.2.7. 翻转句子中单词的顺序....................................................................... 31 1.2.8. 判断整序列是不是二元查找树的后序遍历结果 ................................ 33 1.2.9. 查找最小的 K 个元素-使用最大堆....................................................... 35 1.2.10. 求二叉树中节点的最大距离................................................................ 37 1.3. 面试题集合(二) ........................................................................................ 40 1.3.1. 求 1+2+…+n....................................................................................... 40 1.3.2. 输入一个单向链表,输出该链表中倒第 k 个结点............................. 44 1.3.3. 输入一个已经按升序排序过的数组和一个字.................................... 46 1.3.4. 输入一颗二元查找树,将该树转换为它的镜像.................................... 48 1.3.5. 输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往 右的顺序打印................................................................................................... 49 1.3.6. 在一个字符串中找到第一个只出现一次的字符。如输入 abaccdeff,则输出 b 52 1.3.7. n 个字(0,1,…,n-1)形成一个圆圈 .................................................. 53 1.3.8. 定义 Fibonacci 列 ............................................................................ 58 1.3.9. 左移递减列查找某一个.........................................

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值