给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/single-number
作者:本人
思路:
建立一个哈希表,遍历数组,如果哈希表中有这个数组中这个数,那就删除,如果没有那就添加。
因为题目说了,其余元素都出现两次,所以进过这样的操作,哈希表中只有那一个我们想要的结果了,遍历哈希表,return即可。
- class Solution {
- public int singleNumber(int[] nums) {
- int len = nums.length;
- Map
map = new HashMap(); - for (int i = 0; i < len; i++) {
- if (map.containsKey(nums[i])){
- map.remove(nums[i]);
- }else {
- map.put(nums[i],nums[i]);
- }
- }
- List
list =new ArrayList<> (map.values()) ; - return list.get(0);
- }
- }
效果不好,肯定有更好的方法
作者:本人
思路
先将数组排序,然后让数组的第一个 - 第二个数 + 第三个数 - 第四个数 + 第五个数 ......
最终返回结果即可
例如:
排序后是[ 1, 1, 2, 2, 3] , 1-1+2-2+3 = 3
排序后是[ 1, 1, 2, 3, 3] , 1-1+2-3+3 = 2
排序后是[ 1, 2, 2, 3, 3] , 1-2+2-3+3 = 1
- class Solution {
- public int singleNumber(int[] nums) {
- int len = nums.length;
- Arrays.sort(nums);
- int res = nums[0];
- boolean flag = false;
- for (int i = 1; i < len; i++) {
- if (flag){
- res = res + nums[i];
- }else {
- res = res - nums[i];
- }
- flag = !flag;
- }
- return res;
- }
- }
没想到这个笨办法的效率尽然高于方法1
作者:力扣官方
思路
什么是亦或?
亦或就是 : 同为0,不同为1,注意,指的是数字对应的二进制的每一位:同为0,不同为1
例如:4 ^ 1 = 5
4: 0100
1: 0001
亦或完毕:0101 ,也就是 5
对于这道题,可使用异或运算 ⊕。异或运算有以下三个性质。
- class Solution {
- public int singleNumber(int[] nums) {
- int len = nums.length;
- int res = nums[0];
- for (int i = 1; i < len; i++) {
- res = res ^ nums[i];
- }
- return res ;
- }
- }
版本答案
记住亦或的性质,尤其是:交换律和结合律