寻找数组中第K频繁的元素
问题是:给你一个数组,求解出现次数第K多的元素。当然leetcode上的要求是算法复杂度不能大于O(N*logN)。
首先这个问题我先是在leetcode上看到,当时想了两种做法,做到一半都觉得不是很好,正在思考别的方法。然后在牛客网上看别人的面试经历,看到一个应聘者和用我几乎完全一样的思路尝试在面试中解决这个问题(HashMap-->TreeSet),但是都没解决出来。这个问题确实是一个乍看不难但是要实际解决又会不停发现自己思路有问题的问题,于是我索性记录一下这两种想法和解决之道。
拿到这个问题的时候我第一时间想到了用HashMap解决,键值对的键是数组中的元素的值,值是目前出现的次数,当第一次出现的时候值给1,以后发现已经存在那么就取出值加1再放进去。这个方法的思想是用类似于上一篇博文中的方法来做。核心是用hash算法形成一个元素与储存位置的映射来实现查找操作的常量时间复杂度。这么做的结果是你能在O(N)的算法复杂度情况下得到一个HashMap,它储存了每一种元素和其出现的个数。这个时候一个很具体的问题就出现了,下一步本来需要对出现次数进行一个排序,然后取出出现次数第K大的那个元素。但是问题是键值对的映射方式是从键映射到值,也就是说你用HashMap可以找出值的集合,但是无法找出与这个值对于的键。比如你通过排序知道了最频繁的次数是5,但是你不知道到底谁出现了5次。这个地方其实我要解释一下,不是说你就完全做不到实现反映射,而是第一,HashMap实现的是映射你强行根据值寻找键不符合其设计初衷,第二,实现的过程比较复杂我想需要很大的算法复杂度完全抵消了使用HashMap带来的好处。比如一个键只能对应一个值,但是一个值可能有多个键对应。(每一个数组中的元素都有确定的出现次数,但是出现次数为K的元素可能不止一个)。要解决这些问题等等。真的解决了也就不是这道题目的问题了。
第二时间我想到了用TreeSet,因为它既可以根据你的重写的equal()方法判断是否等于和去重,又可以对你输入数据用comparator进行排序。我就想,我干脆写一个类,里面即方数字本身用于比较是否相等(hashcode和equal),又放当前出现的次数,又实现comparator接口来对当前出现的次数进行排序。我的期望是好的,但是在一开始的思考的时候我忽视了(确实没想到)一个根本的问题,这个问题直接导致我的这个想法完全不能按照我设想的实现。随着你遍历的进行,你的某个数的出现的次数可能从1变到2变到3。所以你有一个不停动态修改TreeSet的内容对象的过程。但是你无法获得TreeSet中值为当前数组值的那个对象的引用。比如说我现在遍历到数组中的5这个元素,于是我去TreeSet中找值为5的对象,但是找不到(没有提供相应的方法)。当然确实也不应该有这样的方法,你想你都知道值是5了,可是你又不知道具体引用的值,TreeSet也没办法帮你。如果用遍历强行去找会导致一个很复杂的过程,算法复杂度高(红黑树的遍历)。同时,TreeSet是按照某种规律排序的,大量的修改其值的操作(通过先删除再add,或者这个问题中的用add覆盖)会影响其效率因为要维护某种顺序。所以这个问题中也不推荐这么做。
虽然以上两种做法都么能直接解决这个问题,但是给我带来了思考。
最后还是做出来了,大致就是第一种方法不过键值对的值是我写的类,最后再用堆排序。这个做法还是挺蠢得我觉得。貌似最佳做法使用桶排序O(N)?以后再研究研究这个。
寻找数组中第K频繁的元素的更多相关文章
- [经典算法题]寻找数组中第K大的数的方法总结
[经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26 字体:[大 中 小] 打印复制链接我要评论 今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...
- 寻找数组中第K大数
1.寻找数组中的第二大数 using System; using System.Collections.Generic; using System.Linq; using System.Text; u ...
- 寻找数组中第K大的数
给定一个数组A,要求找到数组A中第K大的数字.对于这个问题,解决方案有不少,此处我只给出三种: 方法1: 对数组A进行排序,然后遍历一遍就可以找到第K大的数字.该方法的时间复杂度为O(N*logN) ...
- [leetcode]215. Kth Largest Element in an Array 数组中第k大的元素
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- 215。数组中第K个最大元素(堆实现)
class Solution: def findKthLargest(self, nums: List[int], k: int) -> int: """堆排序思想 ...
- 寻找数组中的第K大的元素,多种解法以及分析
遇到了一个很简单而有意思的问题,可以看出不同的算法策略对这个问题求解的优化过程.问题:寻找数组中的第K大的元素. 最简单的想法是直接进行排序,算法复杂度是O(N*logN).这么做很明显比较低效率,因 ...
- C语言:将3*5矩阵中第k列的元素左移到第0列,第k列以后的每列元素依次左移,原来左边的各列依次绕到右边。-在m行m列的二维数组中存放如下规律的数据,
//将3*5矩阵中第k列的元素左移到第0列,第k列以后的每列元素依次左移,原来左边的各列依次绕到右边. #include <stdio.h> #define M 3 #define N 5 ...
- 前端算法题:找出数组中第k大的数字出现多少次
题目:给定一个一维数组,如[1,2,4,4,3,5],找出数组中第k大的数字出现多少次. 例如:第2大的数是4,出现2次,最后输出 4,2 function getNum(arr, k){ // 数组 ...
- 查找数组中第k大的数
问题: 查找出一给定数组中第k大的数.例如[3,2,7,1,8,9,6,5,4],第1大的数是9,第2大的数是8-- 思考:1. 直接从大到小排序,排好序后,第k大的数就是arr[k-1]. 2. ...
随机推荐
- noip模拟赛(10.4) 背包(pack)
[题目描述] 蛤布斯有n种商品,第i种物品的价格为ai,价值为bi.有m个人来向蛤布斯购买商品,每个人每种物品只能购买一个.第j个人有cj的钱,他会不停选择一个能买得起的价格最高的商品买走(如果有多个 ...
- 一个简单的Android富文本TextView实现
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px Helvetica; color: #555555 } p.p2 { margin: 0.0p ...
- android studio 中 .9.png的制作
折腾好久,最后在一个群里面咨询一个朋友才弄好的,用的是1.2.2版,感觉对.9的支持不太好, 1,用一张干净的png图片放在mipmap里面. 2,点击图片右键最后一项,create 9-patch ...
- HTML 学习笔记(URL)
URL也被称为网址 URL可以由单词组成,比如"www.baidu.com" 或者是因特网协议IP地址:192.168.1.253.大多数人在网上冲浪时,会键入网址的域名,因为名称 ...
- python实现一个图灵机器人
这标题就是个噱头...其实用的别人的接口,就是这货. 下面是代码: # -*- coding: utf-8 -*- import urllib,urllib2 import sys import js ...
- 小tips: 使用 等空格实现最小成本中文对齐
一.重见天日第二春 11年的时候,写了篇文章“web页面相关的一些常见可用字符介绍”,这篇文章里面藏了个好东西,就是使用一些空格实现个数不等的中文对齐或等宽.见下表: 字符以及HTML实体 描述以及说 ...
- javascript:查找“跳号”号码
业务背景:航空货运系统中,“货运代理商”会定期从“航空公司”领取一定数量的纸质运单(每张纸上有一个单号),这些单号都是连续的(即:每次可以理解为领取一个“号段”),而且每张单子都要向航空公司交纳一定的 ...
- 2014-2015-2 《Java程序设计》课程学生博客列表
20135101 曹钰晶 20135103 王海宁 20135104 刘 帅 20135105 王雪铖 20135109 高艺桐 20135111 李光豫 20135114 王朝宪 20135116 ...
- MVC5 + EF6 + Bootstrap3 (15) 应用ModelState和Data Annotation做服务器端数据验证
Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc5-ef6-bs3-get-started-server-side-validation.html 系列 ...
- 快速开发之代码生成器(asp.net mvc4 + easyui + knockoutjs)
一.前言 作为一个码农这么多年,一直在想怎么提高我们的编码效率,关于如何提高编码效率,我自己的几点体会 1.清晰的项目结构,要编写代码的地方集中 2.实现相同功能的代码量少并且清晰易懂 3.重复或有规 ...