数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
方法1:哈希
我的代码:好low,因为++count写错了一直找不到原因
class Solution {
public int majorityElement(int[] nums) {
Map<Integer,Integer> map = new HashMap<>();
int count = 0;
for(int i=0;i<nums.length;i++){
if(!map.containsKey(nums[i])){
map.put(nums[i], ++count);
count = 0;
}else{
map.put(nums[i], map.get(nums[i])+1);
}
}
for(int i:map.keySet()){
if(map.get(i) > nums.length/2)
return i;
}
return -1;
}
}
借鉴的代码:count设置成变量,用getOrDefault进行设置,清楚明了。
class Solution {
public int majorityElement(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
int length = nums.length;
for (int i=0; i<nums.length; i++) {
int count = map.getOrDefault(nums[i], 0) + 1;
//如果某个数字出现的个数已经超过数组的一半,直接返回
if (count > length >>2)
return nums[i];
counts.put(nums[i], count);
}
return -1;
}
}
顺变复习下java中hashmap的用法:isEmpty()、size()、put(k,v)、putAll()用于类似拷贝的意思sites2.putAll(sites),把sites的键值对都拷贝给了sites2、remove(k)、containsKey(k)、containsValue(v)、replace(k, v)、sites.replaceAll((key, value) -> value.toUpperCase())用的lambda表达式?、get(k)、getOrDefault(k,default值)、keySet()、values()
foreach()和entrySet()可以一起用:
import java.util.HashMap;
import java.util.Map.Entry;
class Main {
public static void main(String[] args) {
// 创建一个HashMap
HashMap<String, Integer> numbers = new HashMap<>();
numbers.put("One", 1);
numbers.put("Two", 2);
numbers.put("Three", 3);
System.out.println("HashMap: " + numbers);
// 访问 HashMap 中的每一个映射项
System.out.print("Entries: ");
// entrySet()返回了 HashMap 中所有映射项的一个 set 集合视图
// for-each loop 在该视图中访问了每一映射项
for(Entry<String, Integer> entry: numbers.entrySet()) {
System.out.print(entry);
System.out.print(", ");
}
}
}
输出结果为:
HashMap: {One=1, Two=2, Three=3}
Entries: One=1, Two=2, Three=3,
方法2:摩尔投票法
假设数组中每个不同的数字就代表一个国家,而数字的个数就代表这个国家的人数,他们在一起混战,就是每两个两个同归于尽。我们就可以知道那个人数大于数组长度一半的肯定会获胜。
就算退一万步来说,其他的所有人都来攻击这个人数最多的国家,他们每两个两个同归于尽,最终剩下的也是那个众数。
class Solution {
public int majorityElement(int[] num) {
int major = num[0];
int count = 1;
for (int i = 1; i < num.length; i++) {
if (count == 0) {
//前面都消完了,在重新赋值
count++;
major = num[i];
} else if (major == num[i]) {
//自己人,count就加1
count++;
} else {
//不是自己人就同归于尽,消掉一个
count--;
}
}
return major;
}
}