题目
给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的1/k。
给出数组 [3,1,2,3,2,3,3,4,4,4] ,和 k = ,返回 3
数组中只有唯一的主元素
要求时间复杂度为O(n),空间复杂度为O(k)
解题
上一题刚介绍过所用的方法,但是这个确实很复杂的
先利用HashMap实现
public class Solution {
/**
* @param nums: A list of integers
* @param k: As described
* @return: The majority number
*/
public int majorityNumber(ArrayList<Integer> nums, int k) {
// write your code
if(nums == null)
return 0;
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
int majority = 0;
for(int i = 0;i<nums.size(); i++){
int num = nums.get(i);
if(map.containsKey(num)){
map.put(num,map.get(num) + 1);
}else{
map.put(num,1);
}
if(map.get(num)*k > nums.size()){
majority = num;
break;
}
}
return majority;
}
}
Java Code
总耗时: 1655 ms
class Solution:
"""
@param nums: A list of integers
@param k: As described
@return: The majority number
"""
def majorityNumber(self, nums, k):
# write your code here
if nums == None:
return 0
d = {}
majority = 0
for num in nums:
if num in d:
d[num] += 1
else:
d[num] = 1
if d[num]*k > len(nums):
majority = num
break
return majority
Python Code
总耗时: 307 ms
更新HashMap的方法
import java.util.*;
public class Solution {
/**
* @param nums: A list of integers
* @param k: As described
* @return: The majority number
*/
public int majorityNumber(ArrayList<Integer> nums, int k) {
// write your code
HashMap<Integer,int[]> counters = new HashMap<Integer,int[]>(); // 数组定义key 效率比较高
for(Integer num : nums){
int[] value = counters.get(num);
if(value == null){
counters.put(num,new int[]{1});
}else{
value[0]++; // 直接 + 1
} }
k = nums.size()/k;
for(Map.Entry<Integer,int[]> entry:counters.entrySet()){
int[] value = entry.getValue();
if(value[0] > k){
return entry.getKey();
}
}
return Integer.MAX_VALUE;
}
}
进阶2:思路是,如果出现k个不一样的数,就抵消掉。这里需要用巧妙的数据结构来记录Candidates,并使得如下操作均为O(1):
1. 加入一个Candidate/给某个Candidate出现次数+1
2. Candidates中是否存在某个数
3. Candidates中所有数的出现次数 - 1
4. 移除出现次数为0的Candidates
对于1,2两个操作,我们自然可以想到使用Hash表来完成。对于第4两个操作,我们希望能够有出现次数最少的Candidate的信息,但是如果使用Heap则并非O(1)的时间复杂度。注意到每一次加入一个Candidate时,count均为1,每一次给改变一个Candidate出现次数时,也只涉及到加1运算。因此,如果我们能维护Candidates的有序性,就可以容易的解决这个问题。方法是,使用LinkedList。与普通的LinkedList不同的是,我们将所有出现次数相同的Candidate放在一个Bucket里,Bucket内部的Candidate用Doubly Linked List链接起来,Bucket之间也用Doubly Linked List链接起来。这样针对+1运算,我们只需要通过Hash表找到对应的Candidate,把Candidate从当前的Bucket移动到下一个Bucket(出现次数+1的Bucket)。另外,对于所有数-1的操作,我们记录全局的一个Base,每次-1操作,则Base+1。如果Base和Buckets中的第一个Bucket中的Candidates的出现次数相同,则整个删除第一个Bucket。最后,我们会得到最大k-1个Candidates,重新遍历一遍整个数组,用O(k)的Hash记录这k-1个Candidates的出现次数,就可以验证谁是真正的主元素。
public class Solution {
/**
* @param nums: A list of integers
* @param k: As described
* @return: The majority number
*/
public int majorityNumber(ArrayList<Integer> nums, int k) {
// write your code
HashMap<Integer,Integer> counters = new HashMap<Integer,Integer>();
for(Integer num : nums){
if(!counters.containsKey(num)){
counters.put(num,1);
}else{
counters.put(num,counters.get(num) + 1);
}
if( counters.size() >= k){
removeKey(counters);// 清空
} }
if( counters.size() ==0) {
return Integer.MIN_VALUE;
}
for(Integer i: counters.keySet()){
counters.put(i,0);
}
for(Integer i :nums){
if(counters.containsKey(i)){
counters.put(i,counters.get(i) + 1);
}
}
int maxCounter = 0;
int maxKey = 0;
for (Integer i : counters.keySet()) {
if (counters.get(i) > maxCounter) {
maxCounter = counters.get(i);
maxKey = i;
}
} return maxKey;
}
private void removeKey(HashMap<Integer, Integer> counters) {
Set<Integer> keySet = counters.keySet();
List<Integer> removeList = new ArrayList<>();
for (Integer key : keySet) {
counters.put(key, counters.get(key) - 1);
if (counters.get(key) == 0) {
removeList.add(key);
}
}
for (Integer key : removeList) {
counters.remove(key);
}
}
}
Python Code
总耗时: 1725 ms
表示没有理解透彻
lintcode 中等题:majority number III主元素III的更多相关文章
-
lintcode 中等题:Majority number II 主元素 II
题目 主元素II 给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的三分之一. 样例 给出数组[1,2,1,2,1,3,3] 返回 1 注意 数组中只有唯一的主元素 挑战 要求时 ...
-
Majority Element:主元素
Given an array of size n, find the majority element. The majority element is the element that appear ...
-
【Lintcode】046.Majority Number
题目: Given an array of integers, the majority number is the number that occurs more than half of the ...
-
lintcode 中等题:Single number III 落单的数III
题目 落单的数 III 给出2*n + 2个的数字,除其中两个数字之外其他每个数字均出现两次,找到这两个数字. 样例 给出 [1,2,2,3,4,4,5,3],返回 1和5 挑战 O(n)时间复杂度, ...
-
lintcode 中等题:subsets II 带重复元素的子集
题目 带重复元素的子集 给定一个可能具有重复数字的列表,返回其所有可能的子集 样例 如果 S = [1,2,2],一个可能的答案为: [ [2], [1], [1,2,2], [2,2], [1,2] ...
-
lintcode 中等题:kth-largest-element 第k大元素
题目 第k大元素 在数组中找到第k大的元素 样例 给出数组[9,3,2,4,8],第三大的元素是4 给出数组 [1,2,3,4,5],第一大的元素是5,第二大的元素是4,第三大的元素是3,以此类推 注 ...
-
lintcode 中等题:find the missing number 寻找缺失的数
题目 寻找缺失的数 给出一个包含 0 .. N 中 N 个数的序列,找出0 .. N 中没有出现在序列中的那个数. 样例 N = 4 且序列为 [0, 1, 3] 时,缺失的数为2. 注意 可以改变序 ...
-
lintcode 中等题:Singleton number II 落单的数 II
题目 落单的数 II 给出3*n + 1 个的数字,除其中一个数字之外其他每个数字均出现三次,找到这个数字. 样例 给出 [1,1,2,3,3,3,2,2,4,1] ,返回 4 挑战 一次遍历,常数级 ...
-
lintcode 中等题:Letter Combinations of a Phone Number 电话号码的字母组合
题目 电话号码的字母组合 给一个数字字符串,每个数字代表一个字母,请返回其所有可能的字母组合. 下图的手机按键图,就表示了每个数字可以代表的字母. 样例 给定 "23" 返回 [& ...
随机推荐
-
七种机器内部排序的原理与C语言实现,并计算它们的比较次数与移动次数。
内部排序是指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列. 排序是计算机程序设计中的一种重要操作,其功能是对一个数据元素集合或序列重新排列成一个按数据元素某个相知有序的序列.排序分为 ...
-
android之listView定位到指定行同一时候隐藏输入键盘
帮别人该bug遇到的一个问题,记录下来. listView.setSelection(a); 这种方法能够让让你的listview定位到指定行 可是假设紧接着运行隐藏输入键盘的代码.则会有bug.这个 ...
-
MPP 一、Greenplum 集群安装
Installating and Initializing a Greenplum Database System... 1 安装说明 1.1 环境说明 名称 版本 下载地址 虚拟机 Oracle V ...
-
angular2安装笔记
主要摘自:http://www.runoob.com/angularjs2/angularjs2-typescript-setup.html http://blog.csdn.net/lgpwwa/a ...
-
UE4 UnLoadStreamLevel
今天测试发现一个bug记录一下,如果把某一个子关卡的加载方式设置为Always Loaded时,调用UnloadStreamLevel时不会执行Completed后面的节点,也就是一直没有完成.
-
Flink RichSourceFunction应用,读关系型数据(mysql)数据写入关系型数据库(mysql)
1. 写在前面 Flink被誉为第四代大数据计算引擎组件,即可以用作基于离线分布式计算,也可以应用于实时计算.Flink的核心是转化为流进行计算.Flink三个核心:Source,Transforma ...
-
最详细的Vuex教程
什么是Vuex? vuex是一个专门为vue.js设计的集中式状态管理架构.状态?我把它理解为在data中的属性需要共享给其他vue组件使用的部分,就叫做状态.简单的说就是data中需要共用的属性. ...
-
ps高级磨皮的7个步骤
1.打开图片 2. 进入通道看红绿蓝哪个通道痘比较明显拖拽复制拷贝哪个通道! 3.选中拷贝的通道--执行滤镜--其他--高反差保留 4.在执行图像--计算(混合模式强光)--计算三次 5.选alpha ...
-
ruby Enumerator::lazy
当一个很大的数组或集合需要做循环操作的时候,一次性把数据放到内存会有很大弊端.这时lazy就派上用场了.Float::INFINITY 是无穷大意思 举个例子 取出1到无穷大对7整除余数为0的前10个 ...
-
在c和c++中的求绝对值
在c语言中,根据类型的不同,求绝对值函数也不同. int abs(int x) double fabs(double x) 求int类型用abs,求浮点类型用fabs. 而且这两个函数的所在头文件也不 ...