题目背景
LeetCode 136. 只出现一次的数字
给你一个非空整数数组 nums,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
示例:
输入:nums = [4, 1, 2, 1, 2]
输出:4
约束条件: • 1 <= nums.length <= 3 * 10^4 • -3 * 10^4 <= nums[i] <= 3 * 10^4 • 除了某个元素只出现一次外,其余每个元素均出现两次
方法一:暴力遍历(排序 + 配对)
思路分析 一个直观的想法是:将数组排序后,相同的数字必然相邻。通过成对检查,就能找到那个'落单'的元素。
代码实现:
int singleNumber(vector<int>& nums) {
sort(nums.begin(), nums.end()); // 排序,让相同数字相邻
for (int i = 0; i < nums.size(); i += 2) {
// 如果当前是最后一个元素,或与下一个元素不相等
if (i == nums.size() - 1 || nums[i] != nums[i + 1]) {
return nums[i];
}
}
return -1;
}
复杂度分析 • 时间复杂度:O(n log n),主要开销在于排序 • 空间复杂度:O(1),使用常数级别额外空间
虽然思路清晰,但排序的时间复杂度成为了瓶颈。在算法世界中,我们总是追求更优的解法。那么,能否在线性时间内解决这个问题呢?
方法二:哈希表辅助(空间换时间)
思路分析 利用集合(Set)的唯一性:遍历数组,若数字已在集合中则移除,否则加入。最后剩下的就是只出现一次的数字。
代码实现:
int singleNumber(vector<int>& nums) {
unordered_set<int> numSet;
for (int num : nums) {
if (numSet.find(num) != numSet.end()) {
numSet.(num);
} {
numSet.(num);
}
}
*numSet.();
}

