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?
第一次,考虑的时间复杂度需要线性,则最多只能套一层循环。
只有一个数组出现一次,其他出现两次,则该数组长度n必须是奇数,利用hash表,建立一个(n + 1)/ 2 的链表数组。key = (n + 1)/ 2
然后在hash表中找到长度为1,即hash[i].next == null 的节点
public class Node{ public Node(int num, Node node) { next = node; number = num; } public Node next; public int number; } public class Solution { public int SingleNumber(int[] nums) { int size = (nums.Length + 1) / 2; Node node = null; Node[] nodeList = new Node[size]; for(int i = 0; i < size; i++) { nodeList[i] = node; } for(int i = 0; i < nums.Length; i++) { Node eachNode = new Node(nums[i], null); int location = i % (size - 1); if(nodeList[location] == null) { nodeList[location] = eachNode; } else { nodeList[location].next = eachNode; } } for(int i = 0; i < size; i++) { if(nodeList[i].next == null) { return nodeList[i].number; } } return 0; } }
但是,忽略了不同的值经过hash计算后可能得到同一个值,所以这种方法是不对的。
第二次,使用异或计算,两个相同的整数进行异或计算则得到的是0;一个整数和0进行异或计算则为这个整数本身。
并且异或满足 a ^ b = b ^ a
所以,这个数组中出了要找出的数字,其他数字都是成对出现的
eg. nums[A, B, C, B ,A] A ^ B ^ C ^ B ^ A
= (A ^ A) ^ (B ^ B) ^ C
= 0 ^ 0 ^ C
= 0 ^ C
= C
C语言代码如下:
int singleNumber(int* nums, int numsSize) { int result = *nums; for(int i = 1; i < numsSize; i++) { result ^= nums[i]; } return result; }