LeetCode初级算法之数组:136 只出现一次的元素
只出现一次的元素
题目地址:https://leetcode-cn.com/problems/single-number/
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
题目信息
输入:整数数组(只有一个数单个,其他数全部是两次的数组)
输出:整数(那个单个的数)
额外:时间复杂度O(n),空间复杂度O(1)
思考
一开始看漏了信息以为只有数组里只有一个不重复其他都是重复不限次数,忽略了重复只有2次。所以想到的只有万能的map计数,无论是找出现次数最多的还是出现一次的啥都可以。但并不满足空间复杂度,为了满足空间复杂度不使用额外记录那就是暴力扫描n^2,说到扫描就还对应一个更优的方式就是排序后再扫描nlogn但这两种也都不满足线性的时间复杂度。(记得上一篇判断数组是否有重复也有这几种思路使用容器或者双指针扫描)
//方式一:Map计数
public int singleNumber(int[] nums) {
//定义map存<数字i,计数count>
Map<Integer, Integer> map = new HashMap<>();
for (Integer i : nums) {
//如果之前存在计数则加一否则计为第一个
Integer count = map.get(i);
count = count == null ? 1 : ++count;
map.put(i, count);
}
//计数统计结束,遍历所有key找到对应计数是1的
for (Integer i : map.keySet()) {
Integer count = map.get(i);
if (count == 1) {
return i;
}
}
return -1;
}
//方式二:扫描比较
public int singleNumber(int[] nums) {
//排好序、定义两个指针
Arrays.sort(nums);
int start = 0;
int scan = 1;
if(nums.length == 1){
return nums[0];
}
/*
当start不等于scan时
scan停止移动
并且比较差距判断是否出现一次
或者scan停止的地方已经是最后一位
否则继续把start移动到新数字上
*/
while(start < nums.length){
while(nums[start] == nums[scan]){
scan++;
}
if(scan - start == 1){
return nums[start];
}else if(scan == nums.length -1){
return nums[scan];
}
start = scan;
}
return -1;
}
以上两种方法都没有考虑条件中重复数字只是出现两次(输入数组有且只有一个数字唯一其他都是两次),解决的是其他重复数字重复多少都可以,并找到唯一的那个数。目前来说确实在数组中找到唯一数是不可能达到既满足不使用额外空间又满足线性时间复杂度。因此一定是在给出其他重复数字都是两次这样的条件下才可以实现。在这样的条件下有一种方式比上面计数就要优一点点两次相消虽然会使用额外空间但空间与时间比起计数都优化了一点
//方式三
public int singleNumber(int[] nums) {
Set<Integer> set = new HashSet();
for (Integer i : nums) {
if(!set.add(i)){
set.remove(i);
}
}
return set.iterator().next();
}
但最终是要求是时间O(n),空间O(1)。那么只能是原地相消,扫描也不可能因为是时间O(nlogn)。只能遍历一遍并且记录到最后就只剩那一个,这个时候运算熟悉的就会想到使用异或,相同运算结果为0,累计消到最后就剩下单着的那一个
//方式四
public int singleNumber(int[] nums) {
int len = 0;
for (int i : nums) {
len ^= i;
}
return len;
}
总结
这一道题很容易就能想到hash表或者扫描比较的解决方法,主要就是最后利用异或运算的方式实现原地相消和线性的时间复杂度
LeetCode初级算法之数组:136 只出现一次的元素的更多相关文章
- LeetCode初级算法之数组:48 旋转图像
旋转图像 题目地址:https://leetcode-cn.com/problems/rotate-image/ 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: ...
- LeetCode初级算法之数组:66 加一
加一 题目地址:https://leetcode-cn.com/problems/plus-one/ 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一.最高位数字存放在数组的首位, 数 ...
- LeetCode初级算法之数组:122 买卖股票的最佳时机 II
买卖股票的最佳时机 II 题目地址:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/ 给定一个数组,它的第 i ...
- LeetCode初级算法之数组:26 删除排序数组中的重复项
删除排序数组中的重复项 题目地址:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/ 给定一个排序数组,你需要在 ...
- 算法练习LeetCode初级算法之数组
删除数组中的重复项 官方解答: 旋转数组 存在重复元素 只出现一次的数 官方解答: 同一个字符进行两次异或运算就会回到原来的值 两个数组的交集 II import java.util.Arr ...
- LeetCode初级算法之数组:36 有效数独
有效数独 题目地址:https://leetcode-cn.com/problems/valid-sudoku/ 判断一个 9x9 的数独是否有效.只需要根据以下规则,验证已经填入的数字是否有效即可. ...
- LeetCode初级算法之数组:283 移动零
移动零 题目地址:https://leetcode-cn.com/problems/move-zeroes/ 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺 ...
- LeetCode初级算法之数组:350 两个数组的交集 II
两个数组的交集 II 题目地址:https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/ 给定两个数组,编写一个函数来计算它们的交 ...
- LeetCode初级算法之数组:1 两数之和
两数之和 题目地址:https://leetcode-cn.com/problems/two-sum/ 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个整 ...
随机推荐
- nat+端口转发,使得宿主机secureCRT可以访问vbox里linux虚拟机
环境:vbox或者叫vitrualbox连接虚拟机,由于公司内网不能分配IP(不知道是不是这个原因),虚拟机用桥接得不到IP,没法实现虚拟机和宿主互相访问,于是用NAT. 遗憾:NAT是能连接网络,也 ...
- shell编程之条件与分支语句
1.if条件分支语句 if expr1(条件测试) #如果expr1为真,返回0 then commands1 elif expr2 then commands2 .... ... else ...
- uniapp 证书 打包上线GooglePlay app自动升级
uniapp Android证书 打包上线GooglePlay app自动升级 1.Android证书申请 要安装jdk并配置环境变量. keytool -genkey -alias android ...
- linux域名解析引起登陆慢
linux域名解析引起登陆慢的问题在于,ssh去登录这个台机器的时候,本机会去通过域名解析获取登录主机的主机名,所有一旦域名解析是无效的,需要等待较长时间 解决办法一: 将域名解析指到127.0.0. ...
- C语言设计模式(自我揣摩)
NBModule.h #ifndef _NBMODULEFRAME_H__ #define _NBMODULEFRAME_H__ #include "total.h" enum N ...
- Linux(CentOS6.8)配置Redis
1.Redis简介 Redis:REmote DIctionary Server(远程字典服务器). Redis是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分 ...
- 仅需几步,EasyRecovery就能恢复RAID数据
RAID是什么?RAID是具有冗余能力的磁盘阵列,简单的来说就是把相同的数据存储在多个硬盘的不同的地方. 在了解了RAID之后就会知道,RAID中的数据也是有可能丢失的,虽然RAID数据丢失会引发一系 ...
- 教你用Vegas Pro制作视频的遮罩转场特效
很多小伙伴在接触了Vegas之后,都想利用Vegas制作出各种酷炫的特效.小编也是一样. 今天,小编就和大家分享一下,小编近期学会的遮罩转场特效. 首先想要制作遮罩转场效果,需要的素材有:至少两个图片 ...
- guitar pro系列教程(一):Guitar Pro主界面之记谱功能的详细解析【上】
相信弹吉他的朋友们对guitar pro这款软件并不陌生,也有很多朋友用它来看谱制谱.而GP有很多实用功能,能够使我们看谱更清晰,制谱更便捷,所以让我们一起来看看吧 Guitar Pro对初学作曲,特 ...
- 解决Maven项目中pom.xml文件报错(Failure to transfer....)的问题
打开pom.xml文件,查看错误,如果错误类型为:Failure to transfer.........之类的,则表明你的pom中依赖的jar包没有完全下载. 解决方法:找到你本地的maven仓库, ...