解题思路:设绳长为n
因为至少要剪成两段,故对都从剪成两段开始,测到剪成n段,逐个比较最大乘积
算法过程(剪为m段为例):
假设对于绳长为n的绳子,要剪成m段,其最大乘积一定是最为平均的分配方式(即各个段长差值不会超过1)
即维护一个 flag = n/m,mod = n%m
最大乘积应该是(m - mod)段长为flag的段和(mod)段长为(flag + 1)的段相乘
通过上述遍历方式计算每个分解形式的最大乘积逐个比较即可
class Solution {
public:
int cuttingRope(int n) {
int ans = 1;
for(int i = 2; i <= n; i++){
int mod = n % i;
int flag = n / i;
int temp = 1;
for(int j = 1; j <= mod; j++){
temp *= (flag + 1);
}
for(int j = 1; j <= (i -mod); j++){
temp *= flag;
}
if(temp > ans) ans = temp;
}
return ans;
}
};
2.剑指 Offer 57 - II. 和为s的连续正数序列
解题思路:(遇见求连续数组的题应当很快的想到滑动窗口)
滑动窗口(左右边界为l和r)
维持一个sum,sum为窗口内的值的和,
sum < target,r右移
sum > target,l右移,直至sum < target
sum == target,保存窗口对应数组
class Solution {
public:
vector> findContinuousSequence(int target) {
vector> ans;
int sum = 0, l = 1, r = 1;
for(r = 1; r < target; r++){
sum += r;
if(sum > target){
while(l < r && sum > target){
sum -= l++;
}
}
if(sum == target){
vector temp;
for(int i = l; i <= r; i++){
temp.push_back(i);
}
ans.push_back(temp);
}
}
return ans;
}
};
3.剑指 Offer 62. 圆圈中最后剩下的数字
解题思路:
这题的动态规划公式很难想,详解见自
约瑟夫环——公式法(递推公式)_陈浅墨的博客-CSDN博客_约瑟夫问题
/*
n = 5, m = 3;
4-0 1 2 3 4
0-3 4 0 1
1-1 3 4
1-1 3
0-3
*/
class Solution {
public:
int lastRemaining(int n, int m) {
int winner = 0;
for(int last = 1; last <= n; last++){
winner = (winner + m)%(last);
}
return winner;
}
};
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)