1.阶乘后的0
题目:给定一个整数 n,返回 n! 结果尾数中零的数量。
思路:自习观察可知,多少个0取决于数字的因数有多少个5(包括5自身),因为5×2就有一个0,偶数肯定有2,偶数的数量比5更多,所以因数中5的数量就是阶乘的结果中0的数量
/**
* @param {number} n
* @return {number}
*/
const trailingZeroes = function (n) {
let res = arguments[1] ? arguments[1] : 0;
if (n < 5) {
return res;
}
v = (n / 5) | 0;
return trailingZeroes(v, res + v);
};
2.旋转数组
题目:给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
思路:首先,用pop和unshift方法,执行k次即可
/**
* @param {number[]} nums
* @param {number} k
* @return {void} Do not return anything, modify nums in-place instead.
*/
var rotate = function(nums, k) {
for (let i = 0; i < k; i++) {
let item = nums.pop();
nums.unshift(item);
}
};
优化方向:一次性完成操作。向右移动k,其实就是将后k个元素插入到前面。,用splice方法
/**
* @param {number[]} nums
* @param {number} k
* @return {void} Do not return anything, modify nums in-place instead.
*/
var rotate = function(nums, k) {
if (nums.length < 2) return;
const l = k % nums.length;
nums.splice(0, 0, ...nums.splice(nums.length - l, l));
};
第三种方法:不修改原数组,借助一个新数组,将原数组的元素拷贝到新数组,然后替换即可
/**
* @param {number[]} nums
* @param {number} k
* @return {void} Do not return anything, modify nums in-place instead.
*/
var rotate = function(nums, k) {
if (nums.length < 2) return;
const l = nums.length;
const v = k % l;
const res = [];
nums.forEach((i, index) => {
res[(index + v) % l] = i;
});
nums.splice(0, l, ...res);
};
3.颠倒二进制位
题目:颠倒给定的 32 位无符号整数的二进制位。
思路:转换成字符串然后颠倒,再转换成数字
/**
* @param {number} n - a positive integer
* @return {number} - a positive integer
*/
var reverseBits = function(n) {
const s = n.toString(2).padStart(32, "0");
let res = "";
for (let i = 0, l = s.length; i < l; i++) {
res = s[i] + res;
}
return parseInt(res, 2);
};
4.位1的个数
题目:编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
思路:转换成字符串,然后统计1的个数即可
/**
* @param {number} n - a positive integer
* @return {number}
*/
var hammingWeight = function(n) {
const s = n.toString(2);
let res = 0;
for (let i = 0, l = s.length; i < l; i++) {
if (s[i] === "1") res++;
}
return res;
};
5.打家劫舍
题目:
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
思路:这题的思路很重要,动态规划即可,和斐波那契数列很相似。
核心就是,对于长度为n的数组,前n个的最优解,是n-1的最优解和n-2的最优解+n的较大值
即Lfn(n)=math.max(fn(n-1),fn(n-2)+n)
/**
* @param {number[]} nums
* @return {number}
*/
var rob = function (nums) {
const l = nums.length;
if (!l) return 0;
let v1 = 0;
let v2 = nums[0];
let temp;
for (let i = 1; i < l; i++) {
temp = v2;
v2 = Math.max(v1 + nums[i], v2);
v1 = temp;
}
return v2;
};