只出现一次的元素

题目地址: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. RPS/RFS/ GRO

    http://www.cnhalo.net/2016/09/13/linux-gro/ GRO(Generic receive offload): 在napi poll里把小包封装成大包再递交给协议栈 ...

  2. MiniCat:手写Http服务器

    minicat 项目介绍 已实现http基础协议.参数接受.servlet.filter.cookie.多文件上传等.支持NIO. 一款轻量化Http服务器.支持bio.nio两种模式.归属Coody ...

  3. 安装vmware tool

    首先简单介绍一下vmware tool的作用: 1.最大的好处是可以直接把windows界面的文件拖进linux虚拟机内. 2.鼠标可以直接从虚拟机移动到windows等等好处. 步骤 1.点击虚拟机 ...

  4. mysql 创建数据库知识总结

    表设计 库名.表名.字段名必须使用小写字母,"_"分割,且名称长度不超过12个字符并且要做到见名知意. 建议使用InnoDB存储引擎. 存储精确浮点数必须使用DECIMAL替代FL ...

  5. 精尽 MyBatis 源码分析 - MyBatis 初始化(一)之加载 mybatis-config.xml

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  6. java开发两年!这些异常处理的方式你得知道,不然你凭什么涨薪!

    前言 异常是在程序中导致程序中断运行的一种指令流,当异常发生时,程序将直接中断,不再执行后续的任何操作! 示例:两数相除,若不处理任何异常,则只有在正确输入两个数字时,才能显示出运算结果. publi ...

  7. 使用IDM批量抓取音效素材下载

    IDM下载器的站点抓取功能,能够抓取网站上的图片.音频.视频.PDF.压缩包等等文件.更重要的是,能够实现批量抓取操作,省时省力.今天就来看一下,如何用IDM巧妙的批量抓取音效素材. 1.进入音效合辑 ...

  8. python中操作excel数据

    python操作excel,python有提供库 本文介绍openpyxl,他只支持新型的excell( xlsx)格式,读取速度还可以 1.安装 pip install openpyxl 2.使用 ...

  9. nginx学习首页随机模块

    在default.conf下加入这行开启随机模块,在root目录下放入几种不同的html 改完保存下,使用命令检查nginx语法是否正确 nginx -tc /etc/nginx/nginx.conf ...

  10. iOS如何实现语音播报及后台播放

    最近项目刚刚交付,偶然间用到了语音播报和语音搜索的功能.语音搜索我用的是讯飞的demo,感觉效果还不错,感兴趣的话可以去官网上面下载demo,里面讲的特别的详细,不过稍显麻烦一些.语音播报讯飞也有de ...