这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战
这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。
156. 移动零(move-zeroes)
标签
- 简单
- 双指针
题目
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例 1
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
基本思路
看似简单的题目,把0移动到末尾,其他数相对位置不变。
使用两个指针i
和j
,只要nums[i]! == 0
,我们就交换nums[i]
和nums[j]
,再把 j 指针后移,令 j 始终指向最后一个非 0 元素就行
写法实现
function moveZeroes(nums: number[]): void {
if (nums.length !== 0) {
let j = 0;
for (let i = 0; i < nums.length; i++) {
if (nums[i] !== 0) {
[nums[i], nums[j]] = [nums[j], nums[i]]
j++
}
}
}
};
157. 比特位计数 (counting-bits)
标签
- 中等
题目
给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。
示例 1
输入: 2
输出: [0,1,1]
示例 2
输入: 5
输出: [0,1,1,2,1,2]
- 给出时间复杂度为O(n*sizeof(integer)) 的解答非常容易。但你可以在线性时间O(n) 内用一趟扫描做到吗?
- 要求算法的空间复杂度为O(n) 。
基本思路
分奇偶讨论
-
偶数: 最后一位是 0,位移运算右移一位,把 0 移掉,其实就是除以二,发现 1 的个数是不会变的,举个例子
console.log(8>>1) // 4
8
右移一位 是4
其实就是8 / 2 = 4
- 那么 二进制下看
8 => 1000
4 => 100
- 其实就是把最后一位 0 移掉了,
1 的个数是不会变的
所以如果 i 是 偶数, res[i] = res[i / 2]
- 奇数: 奇数其实就很简单,上一个偶数最后一位是 0,加 1,那么 1 的个数就是
res[i] = res[i-1] + 1
写法实现
function countBits(n: number): number[] {
// 0 的 二进制是 0
let res = [0]
for (let i = 1; i <= n; i++) {
if (i % 2 === 0) {
// 偶数情况 最后一位是 0 所以 1 的个数一定和除以2(或者说右移一位) 的那个数一样多,
res[i] = res[i / 2]
} else {
// 奇数情况 因为上一个数偶数末尾必然是 0 现在变成 1,所以个数 + 1
res[i] = res[i-1] + 1
}
}
return res
};
另外向大家着重推荐下这个系列的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列
今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 点击此处交个朋友
Or 搜索我的微信号infinity_9368
,可以聊天说地
加我暗号 "天王盖地虎" 下一句的英文
,验证消息请发给我
presious tower shock the rever monster
,我看到就通过,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧