本文根据左神课程学习总结而来:2021最新左神数据结构算法全家桶

超级水王问题:给你一个数组,出现次数大于数组长度的一半的元素称之为水王数,怎么能快速找到水王数?

内存限制:时间复杂度O(n),额外空间复杂度O(1)——也就是遍历数组的次数为有限次,申请的变量数为有限个

方式一:暴力法

暴力法的思想很简单,用一个hashmap来存放数组中每个元素及其对应的数量,最后遍历hashmap判断有无元素数量大于数组长度一半,有则直接返回水王数,否则返回-1

public static int verify(int[] arr) {if (arr == null || arr.length == 0)return -1;//新建hashmap用于存放数组中每个元素及其对应的数量HashMap<Integer, Integer> hashMap = new HashMap<>();//遍历数组的每个元素for(int num:arr){//如果hashmap中包含该元素,则将该元素的数量+1if(hashMap.containsKey(num))hashMap.put(num,hashMap.get(num)+1);//如果hashmap中不包含key,则将该元素的数量置为1elsehashMap.put(num,1);}//遍历hashmap中每一个entry<k,v>for(Map.Entry<Integer,Integer> record:hashMap.entrySet()){if(record.getValue()>(arr.length>>1))//这里采用位运算,速度快//返回水王数return record.getKey();}return -1;
}

显然,该方法不符合题目的限制,由于使用了hashmap,所以额外的空间复杂度为O(N)


方法二

如何使用有限变量遍历有限次数来完成呢?

思路:从数组第一个元素开始,依次删掉两个不同的数,最后如果有水王数的话,它会剩下来(反过来不成立,也就是剩下来的数不一定是水王数)

如上图所示,依次删除两个不同的元素,相同则不删除,最后只剩下3即是水王数

但请注意,剩下的不一定是水王数,比如:12345,删掉12、34还剩5,但是5不是水王数

这是什么原理呢?我们假设一个数组中有水王数,由于水王数的个数大于所有元素个数的一半,所以如果拿一个非水王数抵消一个水王数,最后还是会剩下水王数;上述删除不同元素的过程就是如此,还可能会存在两个非水王数互相抵消的情况,这样水王数剩下的会更多。

因此我们的算法可以转换为以下两步:

  1. 依次删除数组中两个不同的数
  2. 判断是否有数剩余。如果没有数剩余,则不存在水王;如果有数剩余,我们再遍历一次数组,计算该数的真实的出现次数与数组长度的一半进行比较判断是否为水王数

怎么实现呢?我们只需要两个变量,变量一candidate作为候选用来存放可能的水王数,变量二hp用来存放其剩余个数,按如下规则遍历数组:

  • hp=0 代表没有candidate候选数;hp>0 代表有candidate候选数
  • 如果没有candidate,则设置当前数赋予candidate,即将当前数作为候选数,hp设置为1
  • 如果有candidate,判断当前数是否等于candidate,相等则hp+1,不相等则hp-1

最后判断看hp是否为0,如果不为0,则代表有可能的水王数,再进行计数判断即可

代码实现

public static int waterKing(int[] arr) {if (arr == null || arr.length == 0)return -1;int candidate = 0;int hp = 0;for (int cur : arr) {if (hp == 0) {//没有候选,则将当前数设为候选candidate = cur;hp++;} else if (cur != candidate)//有候选且当前数!=侯选数hp--;else//有候选且当前数=候选数hp++;}//没有候选数剩余,则没有水王数if (hp == 0)return -1;//计算候选数在数组中的元素个数int count = 0;for (int num : arr) {if (num == candidate)count++;}//如果候选数元素个数>数组长度的一半则返回,否则返回-1return count > (arr.length >> 1) ? candidate : -1;
}

左神讲算法——超级水王问题(详解)相关推荐

  1. 左神讲算法——二分法及其拓展

    目录 1. 经典二分例题 2. 拓展例题一:寻找大于等于某数最左侧位置 3. 拓展例题二:局部最小值问题 参考链接:2021最新左神数据结构算法全家桶 1. 经典二分例题 题目一:在一个有序数组中,找 ...

  2. 左神讲算法——异或的高级操作(两数交换+经典面试题)

    目录 1. 异或的性质 2. 两数交换 3. 经典面试例题 参考链接:2021最新左神数据结构算法全家桶 1. 异或的性质 异或可以看成相同为1,不同为0:也可以看作无进位相加,有奇数个1则结果为1, ...

  3. KMP算法之next数组详解

    KMP算法之next数组详解 KMP算法实现原理 KMP算法是一种非常高效的字符串匹配算法,下面我们来讲解一下KMP算如何高效的实现字符串匹配.我们假设如下主串和模式串: int i;//i表示主串的 ...

  4. 算法经典“钓鱼”问题详解 基于贪心算法 C语言描述

    算法经典"钓鱼"问题详解 基于贪心算法 初始条件 在一条水平路边,有 n 2 ≤ n ≤ 25个钓鱼池,从左到右编号为1.2.3.--.n.小明有H1 ≤ H ≤ 16个小时的空余 ...

  5. 操作系统:基于页面置换算法的缓存原理详解(下)

    概述: 在上一篇<操作系统:基于页面置换算法的缓存原理详解(上)>中,我们主要阐述了FIFO.LRU和Clock页面置换算法.接着上一篇说到的,本文也有三个核心算法要讲解.分别是LFU(L ...

  6. 希尔排序基础java代码_java 算法之希尔排序详解及实现代码

    摘要:这篇Java开发技术栏目下的"java 算法之希尔排序详解及实现代码",介绍的技术点是"希尔排序详解.实现代码.希尔排序.Java.实现.代码",希望对大 ...

  7. kmeans python interation flag_机器学习经典算法-logistic回归代码详解

    一.算法简要 我们希望有这么一种函数:接受输入然后预测出类别,这样用于分类.这里,用到了数学中的sigmoid函数,sigmoid函数的具体表达式和函数图象如下: 可以较为清楚的看到,当输入的x小于0 ...

  8. python实验原理_Python实现蒙特卡洛算法小实验过程详解

    蒙特卡洛算法思想 蒙特卡洛(Monte Carlo)法是一类随机算法的统称,提出者是大名鼎鼎的数学家冯·诺伊曼,他在20世纪40年代中期用驰名世界的赌城-摩纳哥的蒙特卡洛来命名这种方法. 通俗的解释一 ...

  9. Matlab中的FCM算法代码及中文详解

    Matlab中的FCM算法代码及中文详解 转自:http://xiaozu.renren.com/xiaozu/106512/336681453 function [center, U, obj_fc ...

  10. 图解机器学习算法(6) | 决策树模型详解(机器学习通关指南·完结)

    作者:韩信子@ShowMeAI 教程地址:https://www.showmeai.tech/tutorials/34 本文地址:https://www.showmeai.tech/article-d ...

最新文章

  1. Java GC 日志详解
  2. python-opencv中的cv2.inRange函数
  3. Python 结巴分词(1)分词
  4. GCC中的分支预测(likely和unlikey)
  5. Multisim14.0 安装教程
  6. 神奇的“弓箭手悖论”,为什么说箭是游出去的?射箭不能瞄准目标
  7. 单片机实验:外部中断按键
  8. java模拟多线程买票问题
  9. 第六章 实验报告(函数与宏定义)
  10. 机器学习基础算法23-XGBoost实践
  11. Cython使用问题集合
  12. 摸个鱼的功夫,搞懂双亲委派机制
  13. 怎么在Mac上修复问题硬盘
  14. 抖音复制微信号跳转微信的链接怎么生成的?
  15. Swiper 轮播插件
  16. Seq2seq - End2end
  17. Python concurrent.future 使用教程及源码初剖
  18. 【微信小编】矩形树图、雷达图
  19. 穹顶灯打不出阴暗面_微服务的阴暗面,解释
  20. 听闻骨折与骨头的故事

热门文章

  1. 美国住宅IP和机房Ip的区别
  2. 商业银行最全数据-66年跨度、100+指标(涵盖业务、股东、高管、员工、审计等数据)
  3. 如何通过树莓派/Python/smtp发送电子邮件
  4. C语言——将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
  5. 基于MATLAB Arnold 的图像置乱加密及解密
  6. 计算机点击管理无效,我的电脑有任务管理器但是点击却没反应是怎么回事
  7. Android Bottom Sheet详解
  8. 数独问题(java)
  9. 扫地阿姨看完都学会了!写给即将正在找工作的Java攻城狮,砥砺前行!
  10. 手绘类短视频怎么制作?从剪辑到配音,后期制作也很重要