01 剪绳子
解法一数学推导:数学推导,分析数字1到5,可以得到当数子是3及以下是不分解,5及以上时分解,只能将数字分解为3和(4或者2)
int cuttingRope(int n) {
//初始条件判断
if(n == 2)
return 1;
if(n == 3)
return 2;
//数学推导划分
int left = n %3;
int num = n/3;
int res = 1;
while(num > 0)
{
res *= 3;
num --;
}
//余数判断
if(left == 2)
{
res *= 2;
}
else if(left == 1)
{
res = res*4/3;
}
return res;
}
解法2动态规划
int cuttingRope(int n) {
//初始条件判断
if (n == 2)
return 1;
if (n == 3)
return 2;
//动态规划
vector<int> maxDp;
maxDp.push_back(1);
maxDp.push_back(1);
maxDp.push_back(1);
maxDp.push_back(2);
for (int j = 4; j < (n+1); j++)
{
int max = maxDp[j - 1];
for (int i = 1; i < j; i++)
{
if ((i * maxDp[j - i]) > max)
{
max = i * maxDp[j - i];
}
if ((i * (j-i)) > max)
{
max = i * (j-i);
}
}
maxDp.push_back(max);
}
return maxDp.back();
}
02 滑动窗口的最大值
解题思路 用一个优先队列记录之前滑过的元素
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
deque<int> record;
for (int i = 0; i < nums.size(); i++)
{
//从后往前清理比当前元素小的记录
while ((! record.empty() )&&(nums[i] > record.back()))
{
record.pop_back();
}
//从前往后清理当前退出的元素
if (((i-k) >= 0 ) && (!record.empty()) &&(nums[i-k] == record.front()))
{
record.pop_front();
}
record.push_back(nums[i]);
if ((i+1 - k) >= 0)
{
res.push_back(record[0]);
}
}
return res;
}
};
03 圆圈中最后剩下的数字
解题思路 这是一个约瑟夫环问题
class Solution {
public:
int lastRemaining(int n, int m) {
int x = 0;
for (int i = 2; i <= n; i++) {
x = (x + m) % i;
}
return x;
}
};