只出现一次的元素

题目地址: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 只出现一次的元素的更多相关文章

  1. LeetCode初级算法之数组:48 旋转图像

    旋转图像 题目地址:https://leetcode-cn.com/problems/rotate-image/ 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: ...

  2. LeetCode初级算法之数组:66 加一

    加一 题目地址:https://leetcode-cn.com/problems/plus-one/ 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一.最高位数字存放在数组的首位, 数 ...

  3. LeetCode初级算法之数组:122 买卖股票的最佳时机 II

    买卖股票的最佳时机 II 题目地址:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/ 给定一个数组,它的第 i ...

  4. LeetCode初级算法之数组:26 删除排序数组中的重复项

    删除排序数组中的重复项 题目地址:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/ 给定一个排序数组,你需要在 ...

  5. 算法练习LeetCode初级算法之数组

    删除数组中的重复项 官方解答: 旋转数组 存在重复元素 只出现一次的数     官方解答:  同一个字符进行两次异或运算就会回到原来的值 两个数组的交集 II import java.util.Arr ...

  6. LeetCode初级算法之数组:36 有效数独

    有效数独 题目地址:https://leetcode-cn.com/problems/valid-sudoku/ 判断一个 9x9 的数独是否有效.只需要根据以下规则,验证已经填入的数字是否有效即可. ...

  7. LeetCode初级算法之数组:283 移动零

    移动零 题目地址:https://leetcode-cn.com/problems/move-zeroes/ 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺 ...

  8. LeetCode初级算法之数组:350 两个数组的交集 II

    两个数组的交集 II 题目地址:https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/ 给定两个数组,编写一个函数来计算它们的交 ...

  9. LeetCode初级算法之数组:1 两数之和

    两数之和 题目地址:https://leetcode-cn.com/problems/two-sum/ 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个整 ...

随机推荐

  1. tcp 客户端 发送syn

    简介 sys_connect->inet_stream_connect->inet_stream_connect->tcp_v4_connect->tcp_connect对于t ...

  2. c++函数声明的位置对函数重载的影响

    c++为了兼容c,也是采用(假)单遍编译.这特别影响函数重载决议(当c++编译器读到一个函数调用语句时,它必须从目前已看到的同名函数中选出最佳函数,哪怕后面的代码中出现了更合适的匹配) 1 #incl ...

  3. 极客mysql02

    mysql 一条更新语句的执行过程: 1.首先客户端通过tcp/ip发送一条sql语句到server层的SQL interface 2.SQL interface接到该请求后,先对该条语句进行解析,验 ...

  4. win10安装MySQL5.7.31 zip版

    因为我之前卸载了安装的(msi,exe)格式的MySQL,现在重新安装zip版的MySQL. 1,下载MySQL MySQL下载地址 : https://dev.mysql.com/downloads ...

  5. Python_字符串_方法

    #字典#把字符串中的字母提取出来改为大写并计数 a="aAsmr3idd4bgs7Dlsf9eAF" b1=[x for x in a if x.isalpha()] b=''.j ...

  6. Html+css 一个简单的网页模板

    一个简单的网页模板,有导航.子菜单.banner部分 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN&q ...

  7. 【转】Java工程师知识图谱

    一.Java工程师知识图谱(思维导图版) 二.Java工程师知识图谱(文字链接版) 专业基石 数据结构 数组 链表 队列 栈 哈希表 堆 树 图 BitMap 算法思想 排序 查找 分支算法 动态规划 ...

  8. 回收站都找不到的文件,EasyRecovery帮你找

    "有人相爱,有人看海,有人深夜两点还在找文件."没错,有人正是不才本人. 细数下来,这已经是本人第五六七八次丢文件了,每次丢的原因很奇怪:删错了.保存完找不到了.或者没有原因就那样 ...

  9. 从维基百科等网站复制公式到MathType中

    在写论文的时候你会想要一些比书本上更好的实例,所以你会在网上寻找资源.当你发现一个你想要的公式时,发现网页公式复制粘贴后太模糊而不适合打印或者投影.这种问题在MathType中如何解决呢? 你可以将网 ...

  10. 仅需几步,EasyRecovery就能恢复RAID数据

    RAID是什么?RAID是具有冗余能力的磁盘阵列,简单的来说就是把相同的数据存储在多个硬盘的不同的地方. 在了解了RAID之后就会知道,RAID中的数据也是有可能丢失的,虽然RAID数据丢失会引发一系 ...