LeetCode算法题-Majority Element(Java实现)
这是悦乐书的第181次更新,第183篇原创
01 看题和准备
今天介绍的是LeetCode算法题中Easy级别的第40题(顺位题号是169)。给定大小为n的数组,找到数组中出现次数超过n/2的元素。假设该数组非空,并且该元素始终存在于数组中。例如:
输入:[3,2,3]
输出:3
输入:[2,2,1,1,1,2,2]
输出:2
本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。
02 第一种解法
我们可以先将数组排序,然后使用for循环遍历前n-1个元素,使用count计算元素出现的次数。
如果第i个元素与第i+1个元素相等,并且i等于数组长度减2,那么count要加两次,否则只用加1此,接着判断count是否大于n/2,如果大于则返回第i个元素。
如果第i个元素与第i+1个元素不相等,这时需要判断i是否大于0并且第i个元素与第i-1个元素是否相等,如果相等,count加1,接着判断count是否大于n/2,如果大于则返回第i个元素,如果不相等,count归为0,再重新开始循环。
因为题目已经表示数组不会为空,所以不需要考虑特殊情况,但是有一点就要考虑,那就是如果没有找到那个出现次数大于n/2的元素,需要返回数组最后一个元素。
public int majorityElement(int[] nums) {
int size = nums.length / 2;
int result = nums[nums.length - 1];
Arrays.sort(nums);
int count = 0;
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] == nums[i + 1]) {
if (i == nums.length - 2) {
count++;
}
count++;
if (count > size) {
return nums[i];
}
} else {
if (i > 0 && nums[i] == nums[i - 1]) {
count++;
if (count > size) {
return nums[i];
}
} else {
count = 0;
}
}
}
return result;
}
此解法的时间复杂度是O(n log(n))+O(n),空间复杂度是O(1)。
03 第二种解法
还是先利用Arrays的排序方法,将数组排序。题目要找的是出现次数大于n/2的元素,那么排过序后,假如存在该元素,那么数组的中间位元素,即nums[n/2]应该就是该元素。
但是,还需要一步判断,如果数组长度是偶数,比如是4,那么中间位元素是nums[2],即是数组第三位元素,这时就需要判断nums[1]和nums[0]是否相等了,如果相等那么返回nums[0]或者nums[n/2 - 1]都行。
public int majorityElement2(int[] nums) {
int len = nums.length;
if(len == 1) return nums[0];
Arrays.sort(nums);
if (len%2 == 0 && nums[0] == nums[len/2 - 1]) {
return nums[0];
}
return nums[len/2];
}
此解法的时间复杂度是O(n log(n)),空间复杂度是O(1)。
04 第三种解法
取一临时变量candidate,存储出现次数大于n/2的元素。取一临时变量count,存储出现次数.
进入循环,判断count是否等于0,等于0,就将当前元素赋值给candidate。接着判断当前元素是否和candidate相等,相等的话count加1,否则减1,直到遍历完所有元素。
此解法,关键在于,碰到当前重复元素就加1,没碰到就减1,如果最后count不等于0,当前重复元素就是出现次数最多的元素,如果count变成0了,说明之前遇到的重复元素和不重复元素出现次数是相等的,相互抵消了,就需要重新去获取当前重复元素了。
public int majorityElement3(int[] nums) {
int count = 0;
int candidate = 0;
for (int i = 0; i < nums.length; i++) {
if (count == 0) {
candidate = nums[i];
}
if (nums[i] == candidate) {
count++;
} else {
count--;
}
}
return candidate;
}
此解法的时间复杂度是O(n),空间复杂度是O(1)。
05 第四种解法
使用HashMap,key存储数组元素,value存储元素出现的次数,如果最后value值大于n/2,那么该key就是出现次数最多的元素。
public int majorityElement4(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
int freq = 0;
for (int i = 0; i < nums.length; i++) {
if (map.containsKey(nums[i])) {
freq = map.get(nums[i]) + 1;
map.put(nums[i], freq);
} else {
freq = 1;
map.put(nums[i], 1);
}
if (freq > nums.length / 2)
return nums[i];
}
return nums[nums.length-1];
}
此解法的时间复杂度是O(n),空间复杂度是O(n)。
06 测试与验证
针对以上四种解法,使用随机的数组和编写了简易的测试代码来测试这几种方法。如下:
public static void main(String[] args) {
Easy_169_MajorityElement instance = new Easy_169_MajorityElement();
int[] arg = { 3, 2, 3, 1, 2, 3, 2, 3};
long start = System.nanoTime();
int result = instance.majorityElement(arg);
long end = System.nanoTime();
System.out.println("majorityElement---输入:" + Arrays.toString(arg) + " , 输出:" + result + " , 用时:" + ((end - start) / 1000) + "微秒");
int[] arg2 = { 3, 2, 3, 1, 2, 3, 2, 3};
long start2 = System.nanoTime();
int result2 = instance.majorityElement2(arg2);
long end2 = System.nanoTime();
System.out.println("majorityElement2---输入:" + Arrays.toString(arg2) + " , 输出:" + result2 + " , 用时:" + ((end2 - start2) / 1000) + "微秒");
int[] arg3 = { 3, 2, 3, 1, 2, 3, 2, 3};
long start3 = System.nanoTime();
int result3 = instance.majorityElement3(arg3);
long end3 = System.nanoTime();
System.out.println("majorityElement3---输入:" + Arrays.toString(arg3) + " , 输出:" + result3 + " , 用时:" + ((end3 - start3) / 1000) + "微秒");
int[] arg4 = { 3, 2, 3, 1, 2, 3, 2, 3};
long start4 = System.nanoTime();
int result4 = instance.majorityElement4(arg4);
long end4 = System.nanoTime();
System.out.println("majorityElement4---输入:" + Arrays.toString(arg4) + " , 输出:" + result4 + " , 用时:" + ((end4 - start4) / 1000) + "微秒");
}
测试结果如下:
majorityElement---输入:[1, 2, 2, 2, 3, 3, 3, 3] , 输出:3 , 用时:211微秒
majorityElement2---输入:[1, 2, 2, 2, 3, 3, 3, 3] , 输出:3 , 用时:5微秒
majorityElement3---输入:[3, 2, 3, 1, 2, 3, 2, 3] , 输出:2 , 用时:4微秒
majorityElement4---输入:[3, 2, 3, 1, 2, 3, 2, 3] , 输出:3 , 用时:62微秒
07 小结
算法专题目前已连续日更超过一个月,算法题文章40+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。
以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!
LeetCode算法题-Majority Element(Java实现)的更多相关文章
- LeetCode算法题-Heaters(Java实现)
这是悦乐书的第239次更新,第252篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第106题(顺位题号是475).冬天来了!您在比赛期间的第一份工作是设计一个固定温暖半径 ...
- LeetCode算法题-Sqrt(Java实现)
这是悦乐书的第158次更新,第160篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第17题(顺位题号是69). 计算并返回x的平方根,其中x保证为非负整数. 由于返回类型 ...
- 【算法】LeetCode算法题-Remove Element
这是悦乐书的第150次更新,第152篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第9题(顺位题号是27).给定整数数组nums和值val,删除nums中所有的val值, ...
- LeetCode算法题-Kth Largest Element in a Stream(Java实现)
这是悦乐书的第296次更新,第315篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第164题(顺位题号是703).设计一个类来查找流中第k个最大元素.请注意,它是排序顺序 ...
- LeetCode算法题-Next Greater Element I(Java实现)
这是悦乐书的第244次更新,第257篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第111题(顺位题号是496).你有两个数组(没有重复)nums1和nums2,其中nu ...
- LeetCode算法题-Implement Queue Using Stacks(Java实现)
这是悦乐书的第195次更新,第201篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第57题(顺位题号是232).使用栈实现队列的以下操作. push(x) - 将元素x推 ...
- LeetCode算法题-Subdomain Visit Count(Java实现)
这是悦乐书的第320次更新,第341篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第189题(顺位题号是811).像"discuss.leetcode.com& ...
- LeetCode算法题-Number of Lines To Write String(Java实现)
这是悦乐书的第319次更新,第340篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第188题(顺位题号是806).我们要将给定字符串S的字母从左到右写成行.每行最大宽度为 ...
- LeetCode算法题-Unique Morse Code Words(Java实现)
这是悦乐书的第318次更新,第339篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第186题(顺位题号是804).国际莫尔斯电码定义了一种标准编码,其中每个字母映射到一系 ...
随机推荐
- Perl的IO操作(2):更多文件句柄模式
open函数除了> >> <这三种最基本的文件句柄模式,还支持更丰富的操作模式,例如管道.其实bash shell支持的重定向模式,perl都支持,即使是2>&1 ...
- GNU C 与 ANSI C(下)
1. 语句表达式 GNU C 把包含在括号中的复合语句看做是一个表达式,称作语句表达式,它可以出现在任何允许表达式的地方.我们可以在语句表达式中使用原本只能在复合语句中使用的循环.局部变量等,例如: ...
- 匿名函数python内置高阶函数以及递归
匿名函数 python定义一个函数通常使用def关键词,后面跟函数名,然后是注释.代码块等. def func(): '''注释''' print('from func') 这样就在全局命名空间定义了 ...
- [转]Angular引入第三方库
本文转自: https://blog.csdn.net/yuzhiqiang_1993/article/details/71215232 版权声明:本文为博主原创文章,转载请注明地址.如果文中有什么纰 ...
- 10.QT-定时器
QObject定时器 需要头文件#include <QTimerEvent> 需要函数 int QObject::startTimer(int interval); //启动定时器,并设 ...
- 【Java每日一题】20170306
20170303问题解析请点击今日问题下方的“[Java每日一题]20170306”查看(问题解析在公众号首发,公众号ID:weknow619) package Mar2017; public cla ...
- 修改CentOS服务器时间为北京时间
购买了VPS,CentOS系统,发现服务器时间与北京时间往往不一致,存在时差. [clive@server workspace]$ date 2018年 05月 30日 星期三 02:02:47 UT ...
- 《锋利的jQuery》笔记:插件的使用和写法
jQuery插件的种类 1.封装对象方法 这种插件是将对象方法封装起来,用于对通过选择器获取的jQuery对象进行操作,是最常见的一种插件.此类插件可以发挥出jQuery选择器的强大优势,有相当一部分 ...
- 一年过去了,25万月薪的AI工程师还存在吗?
导读:2017 年的时候,AI 前线进行了一场有关人工智能领域薪资差异的专题策划,这篇名为<25 万年薪的你与 25 万月薪的他,猎头来谈你们之间的差别>的文章引起了读者们的热烈讨论.一年 ...
- ios12怎么投屏电脑 苹果手机怎么投
Ios12系统发布成功之后,是不是给我们带来更大的惊喜呢.我们只需要利用手机上的屏幕镜像就可以轻松将手机画面投屏至电脑上,那么ios12怎么投屏电脑?下面便是今天所要分享的手机投屏的方法. 使用工具: ...