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?
题意:给定一个整型数组,数组中除了一个数字外,其余数字都出现两次,找到只出现一次的数字。
Note:
要求算法的时间复杂度为O(n),空间复杂度为O(1)。
开始想到了使用排序和使用set的方法,但都不同时满足时间复杂度和空间复杂度的要求。
思路1:先对数组排序,
如果nums[i] == nums[i + 1],则下标i直接加2,跳过这两个数;否则nums[i]为只出现一次的元素。
public int singleNumber(int[] nums) { Arrays.sort(nums); int len = nums.length; int i = 0; while(i < len - 1){ if(nums[i] == nums[i + 1]) i = i + 2; else return nums[i]; } return nums[len - 1]; }
思路2:1. 利用set不包含重复元素的特性。
2. 设数组元素为{a, a, c},则(a + c) * 2 - (a + a + c) = c
将数组中不重复的元素都存入set,并计算所有不重复元素的和sum1;再利用sum1与数组元素总和sum2的关系。
public int singleNumber(int[] nums) { int len = nums.length; Set set = new HashSet(); int sum1 = 0, sum2 = 0; for(int i = 0; i < len; i++){ sum2 += nums[i]; if(!set.contains(nums[i])){ set.add(nums[i]); sum1 += nums[i] * 2; } } return sum1 - sum2; }
思路3:看了LeetCode提供的答案,才知道用异或的方法。
异或的运算规则:仅当对应位的两个数不相同时,结果才为1;否则为0。即位相同(0,0或1,1)时,结果为0,位不同时(0,1或1,0)结果为1。
所以,0异或任何数A,结果还是A
由于数字在计算机是以二进制存储的,每位上都是0或1。
因此对数组中所有元素进行异或,则每对相同的数字都会得0,最后剩下的数字就是只出现一次1次的数字。
public int singleNumber(int[] nums) { int a = 0; for(int num : nums){ a ^= num; } return a; }