剑指offer计划24( 数学中等)---java
1.1、题目1
剑指 Offer 14- I. 剪绳子
1.2、解法
这几天的题都不在行。。。。
1.3、代码
class Solution {
public int cuttingRope(int n) {
int[] dp = new int[n + 1];
dp[2] = 1;
for(int i = 3; i < n + 1; i++){
for(int j = 2; j < i; j++){
dp[i] = Math.max(dp[i], Math.max(j * (i - j), j * dp[i - j]));
}
}
return dp[n];
}
}
2.1、题目2
剑指 Offer 57 - II. 和为s的连续正数序列
2.2、解法
这题返回数组就离谱,为啥不能返回list。。。。。暴力枚举没啥好说的。
2.3、代码
class Solution {
public int[][] findContinuousSequence(int target) {
List<int[]> vec = new ArrayList<int[]>();
int sum = 0, limit = (target - 1) / 2; // (target - 1) / 2 等效于 target / 2 下取整
for (int i = 1; i <= limit; ++i) {
for (int j = i;; ++j) {
sum += j;
if (sum > target) {
sum = 0;
break;
} else if (sum == target) {
int[] res = new int[j - i + 1];
for (int k = i; k <= j; ++k) {
res[k - i] = k;
}
vec.add(res);
sum = 0;
break;
}
}
}
return vec.toArray(new int[vec.size()][]);
}
}
3.1、题目3
剑指 Offer 62. 圆圈中最后剩下的数字
3.2、解法
这题居然是简单题,约瑟夫环,表示看题解的。。。。。。
还用上了动态规划。。。。。。
最后只剩下一个元素,假设这个最后存活的元素为 num, 这个元素最终的的下标一定是0 (因为最后只剩这一个元素),
所以如果我们可以推出上一轮次中这个num的下标,然后根据上一轮num的下标推断出上上一轮num的下标,
直到推断出元素个数为n的那一轮num的下标,那我们就可以根据这个下标获取到最终的元素了。推断过程如下:
首先最后一轮中num的下标一定是0, 这个是已知的。
那上一轮应该是有两个元素,此轮次中 num 的下标为 (0 + m)%n = (0+3)%2 = 1; 说明这一轮删除之前num的下标为1;
再上一轮应该有3个元素,此轮次中 num 的下标为 (1+3)%3 = 1;说明这一轮某元素被删除之前num的下标为1;
再上一轮应该有4个元素,此轮次中 num 的下标为 (1+3)%4 = 0;说明这一轮某元素被删除之前num的下标为0;
再上一轮应该有5个元素,此轮次中 num 的下标为 (0+3)%5 = 3;说明这一轮某元素被删除之前num的下标为3;
....
因为我们要删除的序列为0-n-1, 所以求得下标其实就是求得了最终的结果。比如当n 为5的时候,num的初始下标为3,
所以num就是3,也就是说从0-n-1的序列中, 经过n-1轮的淘汰,3这个元素最终存活下来了,也是最终的结果。
总结一下推导公式:(此轮过后的num下标 + m) % 上轮元素个数 = 上轮num的下标
至于为什么从2开始,你从1开始结果也是一样的。
3.3、代码
class Solution {
public int lastRemaining(int n, int m) {
int ans = 0;
// 最后一轮剩下2个人,所以从2开始反推
for (int i = 2; i <= n; i++) {
ans = (ans + m) % i;
}
return ans;
}
}