1. 找单独的数
刷题前请喊一遍我们的口号:
- 方法不对,刷题白费。
- 节省时间,精准刷题。
本题难度系数:⭐简单
问题描述
在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小 C 快速找到那个拿了独特数字卡片的同学手上的数字是什么。
要求:
- 设计一个算法,使其时间复杂度为 O(n),其中 n 是班级的人数。
- 尽量减少额外空间的使用,以体现你的算法优化能力。
测试样例
样例 1:
输入:
cards = [1, 1, 2, 2, 3, 3, 4, 5, 5]
输出:4
解释:拿到数字 4 的同学是唯一一个没有配对的。
样例 2:
输入:
cards = [0, 1, 0, 1, 2]
输出:2
解释:数字 2 只出现一次,是独特的卡片。
样例 3:
输入:
cards = [7, 3, 3, 7, 10]
输出:10
解释:10 是班级中唯一一个不重复的数字卡片。
约束条件
- 1 ≤ cards.length ≤ 1001
- 0 ≤ cards[i] ≤ 1000
- 班级人数为奇数
- 除了一个数字卡片只出现一次外,其余每个数字卡片都恰好出现两次
解题思路
这个问题要求我们找到一个数组中唯一出现一次的数字,其他数字都恰好出现两次。为了满足时间复杂度为 O(n) 且尽量减少额外空间的使用,我们可以利用异或运算的特性来解决这个问题。
异或运算的特性
- 任何数和 0 做异或运算,结果仍然是原来的数,即
a ^ 0 = a。 - 任何数和其自身做异或运算,结果是 0,即
a ^ a = 0。 - 异或运算满足交换律和结合律,即
a ^ b ^ a = (a ^ a) ^ b = 0 ^ b = b。
基于这些特性,我们可以将数组中的所有数字进行异或运算,最终的结果就是那个唯一出现一次的数字。
算法步骤
- 初始化一个变量
result为 0。 - 遍历数组中的每一个数字,将其与
result进行异或运算,并将结果赋值给result。 - 遍历结束后,
result就是那个唯一出现一次的数字。
这个方法的时间复杂度是 O(n),因为我们只需要遍历一次数组。空间复杂度是 O(1),因为我们只使用了一个额外的变量 result。
开始解题
为了找到唯一出现一次的数字,我们可以利用异或运算的特性。异或运算有以下性质:
- 任何数和 0 做异或运算,结果仍然是原来的数,即
a ^ 0 = a。 - 任何数和其自身做异或运算,结果是 0,即
a ^ a = 0。 - 异或运算满足交换律和结合律,即
a ^ b ^ a = b ^ a ^ a = b ^ 0 = b。
基于这些性质,我们可以通过遍历数组,将所有数字进行异或运算,最终的结果就是那个唯一出现一次的数字。
以下是实现代码:
function solution(cards) {
let result = 0;
for (let num of cards) {
result ^= num;
}
return result;
}
function main() {
// Add your test cases here
console.log(solution([1, 1, 2, 2, 3, 3, 4, 5, 5]) === 4);
console.log(solution([0, 1, 0, 1, 2]) === 2);
console.log(solution([7, 3, 3, 7, 10]) === 10);
}
main();
代码解释
- 初始化结果变量:
result初始化为 0。 - 遍历数组:对数组中的每个元素进行异或运算,并将结果存储在
result中。 - 返回结果:最终
result就是唯一出现一次的数字。
复杂度分析
- 时间复杂度:O(n),其中 n 是数组的长度。我们只需要遍历数组一次。
- 空间复杂度:O(1),只使用了常数个额外空间。
这个方法既满足了时间复杂度为 O(n) 的要求,又最大限度地减少了额外空间的使用。
以上关于1. 找单独的数的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
微信
支付宝