英文原文
Given a non-empty array of integers nums
, every element appears twice except for one. Find that single one.
You must implement a solution with a linear runtime complexity and use only constant extra space.
Example 1:
Input: nums = [2,2,1] Output: 1
Example 2:
Input: nums = [4,1,2,1,2] Output: 4
Example 3:
Input: nums = [1] Output: 1
Constraints:
1 <= nums.length <= 3 * 104
-3 * 104 <= nums[i] <= 3 * 104
- Each element in the array appears twice except for one element which appears only once.
中文题目
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1] 输出: 1
示例 2:
输入: [4,1,2,1,2] 输出: 4
通过代码
高赞题解
大脑的思考过程
这题拿到手,第一反应是用hash表,没有思考细节,只是觉得hash表肯定是可以搞定的,但是空间复杂度是 $O(n)$,不满足题意。
接着开始思考,如何才能做到空间复杂度是 $O(1)$ 呢?脑袋开始疯狂打转,但没有思路。没办法,退回原点。
心想,如果使用暴力破解法,该如何解决,很简单:每次从数组中取一个数,记为cur,然后从剩下的数中查找,如果找不到,则cur即为要找的那个数。这种解法时间复杂度是 $O(n^2)$。
继续思考,如何再继续降低复杂度呢? 想到了排序 !!!
再继续思考,如何能把时间复杂度降到 $O(n)$,有两个突破点:
- 暴力解法做了很多重复的工作
- 要充分利用题目的已有信息
通过第一点,我没有想到思路,不知道有没有 DP 的解法,可能本人对DP使用不是太熟。
通过第二点,我还真找到突破口。反复看了好几篇题目,找到了一个很重要的信息:除了某个元素只出现一次以外,其余每个元素均出现两次。 觉得这是个突破口!!!!——异或运算!
解法一:暴力查找
两次循环,代码略
解法二:排序
使用快排,复杂度 $O(nlogn)$
解法三:
利用 Hash 表,Time: $O(n)$ Space: $O(n)$
class Solution {
public int singleNumber(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
for (Integer i : nums) {
Integer count = map.get(i);
count = count == null ? 1 : ++count;
map.put(i, count);
}
for (Integer i : map.keySet()) {
Integer count = map.get(i);
if (count == 1) {
return i;
}
}
return -1; // can't find it.
}
}
解法四:异或
int ans = nums[0];
if (nums.length > 1) {
for (int i = 1; i < nums.length; i++) {
ans = ans ^ nums[i];
}
}
return ans;
心得
善于题目中的已有信息!!!!
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
546469 | 759880 | 71.9% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|
相似题目
题目 | 难度 |
---|---|
只出现一次的数字 II | 中等 |
只出现一次的数字 III | 中等 |
丢失的数字 | 简单 |
寻找重复数 | 中等 |
找不同 | 简单 |