算法题:剑指 Offer 39. 数组中出现次数超过一半的数字(题目+思路+代码+注释) 时空 1ms击败99.95%用户 一次AC
题目
剑指 Offer 39. 数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
限制:
1 <= 数组长度 <= 50000
注意:本题与主站 169 题相同:https://leetcode-cn.com/problems/majority-element/
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
代码最少的AC办法(2行代码)
题目说有一个数的个数一定超过一半个数,那岂不是最中间的一定是那个数咯,那我们图简单直接排序取中值,确实能通过,耗时在2ms
由于排序过程的时间复杂度是Logn*n,我觉得并不是最快的,没有遵守算法的提前结束原则,肯定还有优化空间。
public int majorityElement2(int[] nums) {
Arrays.sort(nums);
return nums[nums.length / 2];
}
自己实现简单堆统计(推荐)
耗时1ms 超过99.95%的人
查找和插入的过程没有对堆里数据做二分查找和排序,如果数据量大则可以优化查找和插入
假设数组长度为n,既然你说有一个数的数量大于了一半,那这个数组里最多有(n/2)+1个不一样的数。(不懂可以列6个数和7个数看一下就知道了)
那我就定义一个长度为(n/2)+1的数组来存数字,定义一个下标一一对应的数组来存计数。我存的过程中一旦发现某个数的计数已经超过了(n/2)则直接返回这个数即可。
public int majorityElement(int[] nums) {
int mid = nums.length / 2;
int[] numsCopy = new int[mid + 1];
int[] count = new int[mid + 1];
int index = 0, c = 0;
boolean find;
for (int i : nums) {
find = false;
//查
for (int j = 0; j <= index; j++) {
if (numsCopy[j] == i) {
c = count[j] = count[j] + 1;
find = true;
break;
}
}
//插
if (!find) {
numsCopy[index] = i;
c = count[index] = 1;
index++;
}
if (c > mid) {
return i;
}
}
//代码不会到这来的,因为前面一定会返回
return nums[0];
}
摩尔投票法(推荐)
看题解看到的这个方法,确实很牛,但是我看了下时空和我上面的自定义堆效率是一样的,都是1ms和44M多的内存占用,没太大区别,但我还是觉得这个算法是最牛的。
既然你说你的数量是超过一半,那我就从第一个数开始,假设当前数就是对的那个数,下一个数跟当前数相等我就让票数加1,不相等就票数减一,一旦计数降到了0一下就换数到不同的这个数并重置计数器为0。当遍历完所有的数,坚持到最后的一定是那个多的数。
public int majorityElement(int[] nums) {
int now = nums[0];
int count = 0;
for (int i : nums) {
if (i == now) {
count++;
} else {
count--;
if (count <= 0) {
now = i;
}
}
}
return now;
}
哈希法
耗时11ms,速度较慢。占用空间也更多,不建议使用。
public int majorityElement1(int[] nums) {
int mid = nums.length / 2;
HashMap<Integer, Integer> map = new HashMap<>(mid);
for (int i : nums) {
Integer count = map.get(i);
if (count == null) {
count = 1;
} else {
count += 1;
}
if (count > mid) {
return i;
}
map.put(i, count);
}
return nums[0];
}
本文来自博客园,作者:HumorChen99,转载请注明原文链接:https://www.cnblogs.com/HumorChen/p/18039498