这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战
这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。
前面连续的难题,来几个简单点放松下
149. 只出现一次的数字(single-number)
标签
- 简单
- 异或
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1
输入: [2,2,1]
输出: 1
示例 2
输入: [4,1,2,1,2]
输出: 4
基本思路
这就要说到js异或运算符了, 两个要点
- 相同的数异或结果为 0
console.log(1^1) // 0
console.log(6^6) // 0
console.log('a'^'a') // 0
-
与 0 异或 结果为本身
-
满足交换律
console.log(1^2^1) // 2
console.log(1^1^2) // 2
这样的话,我们就非常清楚这个题目怎么处理了,直接遍历异或就能找出那个单着的,dog:那我走?
写法实现
练下 ts 写法,注意 ts 不会影响运行时的 js 行为,也是弱类型的语言。
function singleNumber(nums: number[]): number {
return nums.reduce((acc, cur) => acc ^ cur)
};
150. 数字的补数(number-complement)
标签
- 简单
- 异或
题目
给你一个 正 整数 num ,输出它的补数。补数是对该数的二进制表示取反。
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1
输入:num = 5
输出:2
解释:5 的二进制表示为 101(没有前导零位),其补数为 010。所以你需要输出 2 。
示例 2
输入:num = 1
输出:0
解释:1 的二进制表示为 1(没有前导零位),其补数为 0。所以你需要输出 0 。
基本思路
这里用到异或的另外的性质
-
a ^ b = c可以推出a ^ c = b那么 -
101^010=111=>101^111=010就是我们要的答案了
所以我们只要造一个 跟原数二进制长度相同的 1111.. 然后跟原数异或就得到补数了
另外 toString(2) 和 parseInt(num, 2) 这两个函数的 2,都是二进制的简单转换方式。
写法实现
function findComplement(num: number): number {
let temp = parseInt(new Array(num.toString(2).length).fill(1).join(''), 2)
return temp ^ num
}
今天是不是重新认识了异或这个运算呢
另外向大家着重推荐下这个系列的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列
今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 点击此处交个朋友
Or 搜索我的微信号infinity_9368,可以聊天说地
加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我
presious tower shock the rever monster,我看到就通过,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧