剑指 Offer 14- I. 剪绳子
给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0], k[1]...k[m-1] 。请问 k[0]k[1]...*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
题意理解: 将n拆分成m段,返回每段的乘积的最大值 本人使用暴力枚举,找出的规律 特殊情况,特殊处理 小于3返回n-1, 可以看出拆3则全拆3; 如果余数为1则取一个4,其他为3; 如果余数为2, 则拆成一个2和其他3 m:3 2, 1 m:4 2, 2 m:5 3, 2 m:6 3, 3 m:7 3, 4 m:8 3, 3, 2 m:9 3, 3, 9 m:10 3, 3, 4 m:11 3, 3, 3, 2 m:12 3, 3, 3, 3
提示: 2 <= n <= 58
var cuttingRope = function(n) {
if (n <= 3) return n - 1;
let m = Math.floor(n / 3),
num = n % 3;
if (num === 0) return Math.pow(3, m);
if (num === 1) return Math.pow(3, m - 1) * 4;
return num * Math.pow(3, m)
};
剑指 Offer 57 - II. 和为s的连续正数序列
输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
题意理解: 找出从1开始到target中,连续的数字之和为target的所有情况
- 声明变量currentNum表示当前数的和,arr表示返回的结果,list存储当前和小于target的值
- i=1,遍历target
- 如果currentNum===target,则list中的值就符合条件,是真确答案之一,将list前面以为出数组,当前数加入数组,并计算当前值,i累加
- 如果currentNum< target,则当前面数加入数组,并计算当前值,i累加
- 如果currentNum> target,则去掉前面的数字,并计算当前值
1 <= target <= 10^5
var findContinuousSequence = function(target) {
let currentNum = 0;
const arr = [];
let list = [];
let i = 1;
while (i <= target) {
if (currentNum === target) {
arr.push([...list])
list.push(i)
const deleteNum = list.shift()
currentNum += i;
currentNum -= deleteNum;
i++
} else if (currentNum < target) {
list.push(i)
currentNum += i;
i++
} else {
const deleteNum = list.shift()
currentNum -= deleteNum;
}
}
return arr;
};
剑指 Offer 62. 圆圈中最后剩下的数字
0, 1, ···, n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。
题意理解: 0-n-1个数字将排成一个环,一次删除换种第m个数字,知道只剩下最后一个数字 找规律: f(n) = (f( n - 1 ) + m) % n 参考此处
以n = 5, m = 3为例 初始化 0 1 2 3 4 第一轮 0 1 3 4 去除2 第二轮 1 3 4 去除0 第三轮 1 3 去除4 第四轮 3 去除1
以n = 4, m = 3为例 初始化 0 1 2 3 第一轮 0 1 3 去除2 第二轮 0 3 去除1 第三轮 0 去除3
以n = 3, m = 3为例 初始化 0 1 2 第一轮 0 1 去除2 第二轮 1 去除1
示例 1: 输入: n = 5, m = 3 输出: 3
示例 2: 输入: n = 10, m = 17 输出: 2
限制: 1 <= n <= 10^5 1 <= m <= 10^6
动态规划 反序
var lastRemaining = function(n, m) {
let x = 0;
for (let i = 2; i <= n; i++) {
x = (x + m) % i
}
return x
};
暴力
var lastRemaining = function(n, m) {
let arr = [];
for (let i = 0; i < n; i++) {
arr[i] = i
}
let num = 0;
let currentIndex = 0;
while (arr.length > 1) {
num++;
if (num === m) {
arr.splice(currentIndex, 1);
currentIndex--;
num = 0;
}
if (currentIndex >= arr.length - 1) {
currentIndex = 0;
} else {
currentIndex++;
}
}
return arr[0]
};