欢迎查看和关注一个开源的个人学习计算机科学知识成长记录(前后端,数据结构与算法)
136. 只出现一次的数字 - 力扣(LeetCode) (leetcode-cn.com)
题解
考虑到题目要求时间具有线性时间复杂度,同时不用额外空间,想到了就在原数组上做操作:
- 先排序,变成有序数组
- 有序数组,按照题目条件,每个元素要么出现一次,要么出现两次
- 出现两次的数字,在排序后会挨在一起
- 取连续的两个数字,判断数字是否相等
- 因为有可能取到最后的数组,就是一个奇数数组,因此就会是当前的结果
- 如果出现一次的出现在中间就会是两个中的第一个数字
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
nums = nums.sort((a,b)=>a-b);
let len = 0;
while(len<=nums.length+1){
const cur = nums.slice(len,len+2)
if(cur.length == 2){
if(cur[0]!=cur[1]){
return cur[0]
}
}else if(cur.length == 1){
return cur[0]
}
len = len + 2;
}
};
执行结果:通过
执行用时:84 ms, 在所有 JavaScript 提交中击败了33.65%的用户
内存消耗:44.4 MB, 在所有 JavaScript 提交中击败了13.83%的用户
通过测试用例:61 / 61
位运算
既满足时间复杂度又满足空间复杂度,就要提到位运算中的异或运算 XOR,主要因为异或运算有以下几个特点:
- 一个数和 0 做 XOR 运算等于本身:a⊕0 = a
- 一个数和其本身做 XOR 运算等于 0:a⊕a = 0
- XOR 运算满足交换律和结合律:a⊕b⊕a = (a⊕a)⊕b = 0⊕b = b
- 故而在以上的基础条件上,将所有数字按照顺序做抑或运算,最后剩下的结果即为唯一的数字
- 时间复杂度:O(n),空间复杂度:O(1)
var singleNumber = function(nums){
let ans = 0;
for(let num of nums){
ans ^= num;
}
return ans;
}
执行结果:通过
执行用时:76 ms, 在所有 JavaScript 提交中击败了55.10%的用户
内存消耗:43.4 MB, 在所有 JavaScript 提交中击败了24.40%的用户
通过测试用例:61 / 61
参考链接
136. 只出现一次的数字 - 力扣(LeetCode) (leetcode-cn.com)
只出现一次的数字 - 只出现一次的数字 - 力扣(LeetCode) (leetcode-cn.com)
画解算法:136. 只出现一次的数字 - 只出现一次的数字 - 力扣(LeetCode) (leetcode-cn.com)