博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode]--136. Single Number
阅读量:7060 次
发布时间:2019-06-28

本文共 3140 字,大约阅读时间需要 10 分钟。

Given an array of integers, every element appears twice except for one. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

耐心看下我的思想演变过程吧,可能是大脑缺氧,用List装下标。

public int singleNumber(int[] nums) {        if (nums.length == 1)            return nums[0];        ArrayList
temp = new ArrayList
(); for (int i = 0; i < nums.length - 1; i++) { if (temp.contains(i)) continue; for (int j = i + 1; j < nums.length; j++) { if (temp.contains(j)) continue; if (nums[i] == nums[j]) { System.out.println(i + "---" + j); temp.add(i); temp.add(j); break; } } } for (int i = 0; i < nums.length; i++) { if (!temp.contains(i)) { return nums[i]; } } return 0; }

代码逻辑和实现应该没有问题,测试也通过了,就是提交的时候超时了,于是我就想着用空间去换取时间。

public int singleNumber1(int[] nums) {        ArrayList
preList = new ArrayList
(); ArrayList
list = new ArrayList
(); int len = nums.length; int[] flag = new int[len]; Arrays.fill(flag, 0); for (int i = 0; i < len; i++) { if (!preList.contains(nums[i])) { preList.add(nums[i]); } else { flag[i] = 1; } if (!list.contains(nums[len - 1 - i])) { list.add(nums[len - 1 - i]); } else { flag[len - 1 - i] = 1; } } for (int i = 0; i < flag.length; i++) { if (flag[i] == 0) { return nums[i]; } } return 0; }

这也是一种方法其实,两头同时遍历,一次遍历就可以解决问题,但是仔细想想其实复杂度没减。

再使用暴力搜索,遍历数组,发现两个元素相等,则将这两个元素的标志位置为1,最后返回标志位为0的元素即可。时间复杂度O(n^2)没有AC,Status:Time Limit Exceed

public int singleNumber2(int[] nums) {        int n = nums.length;        if (n == 1)            return nums[0];        int[] flag = new int[n];        for (int i = 0; i < n; i++) {            if (flag[i] == 1)                continue;            else {                for (int j = i + 1; j < n; j++) {                    if (nums[i] == nums[j]) {                        flag[i] = 1;                        flag[j] = 1;                    }                }            }        }        for (int i = 0; i < n; i++) {            if (flag[i] == 0)                return nums[i];        }        return 0;    }

后来用这个就是通过的,Accept!真是高兴,但是又不服,这个其实和第一次一样,只是用数组装flag。而且我觉得很有可能是偶然通过的。

其实我记得有个位运算很简单也很高效。但是说实话,一般来说大家对位运算都有种神秘陌生对吧,我也不例外,虽然知道,但是用起来很困难。

利用异或操作。异或的性质1:交换律a ^ b = b ^ a,性质2:0 ^ a = a。于是利用交换律可以将数组假想成相同元素全部相邻,于是将所有元素依次做异或操作,相同元素异或为0,最终剩下的元素就为Single Number。时间复杂度O(n),空间复杂度O(1)

public int singleNumber(int[] A) {        if(A == null || A.length == 0) {            return -1;        }        int rst = 0;        for (int i = 0; i < A.length; i++) {            rst ^= A[i];        }        return rst;    }

所以还是强烈建议用后面这种。

转载地址:http://vcbll.baihongyu.com/

你可能感兴趣的文章
算法1--
查看>>
关于“华为”的大数据分析
查看>>
Proguard随笔
查看>>
BUG:ie8不支持indexOf()
查看>>
vue.js入门
查看>>
ORB-SLAM2学习3 MapPoint.h Map.h
查看>>
推荐的 MongoDB 安装文档
查看>>
ubuntu cron设置和开启日志
查看>>
在Android中支持表情
查看>>
js制作圆角按钮(兼容谷歌,ie7,ie8)
查看>>
细说websocket - php篇
查看>>
Ajax请求与浏览器缓存
查看>>
获取页面所有参数
查看>>
NServiceBus VS MassTransit 从 stackoverflow.com 翻译而来,希望对这两个技术比较关心的同学有帮助...
查看>>
阿里云OSS图片格式错误导致跳出新页面链接问题
查看>>
常用函数
查看>>
jdk logging解析
查看>>
#001 HTML快速入门讲解
查看>>
.Net 之不同AppDomin之间通讯
查看>>
[Java 基础] 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法
查看>>