贪心算法6
LeetCode 738 单调递增的数字 2023.11.30
int monotoneIncreasingDigits(int n) {
/*暴力求解,会超时
for (int i = n; i > 0; i--)
{
int sym = 1;
int stop = i;
int right = i%10;
while (stop >= 10)
{
stop /= 10;
int left = stop%10;
if(left > right)
{
sym = 0;
break;
}
right = left;
}
if(sym == 1)
return i;
}
return 0;
*/
//将int转为字符串型
string strNum = to_string(n);
//flag用来标记赋值9从哪个位置开始,后面全是9,默认为最后一位的下一位
int flag = strNum.size();
for (int i = flag-1; i > 0; i--)
{
//判断前一位数字比后一位大时,记录后一位的位置,并将前一位减小一位,保证最后生成值小于原值
//只判断一次原因:该位后面都要设为9,一定比前面大
if(strNum[i-1] > strNum[i])
{
flag = i;
strNum[i-1]--;
}
}
//将flag及其后面的值都改为9
for (int i = flag; i < strNum.size(); i++)
{
strNum[i] = '9';
}
//将字符串类型转为int型并输出
return stoi(strNum);
}
动态规划算法1
动规五部曲
- 确定dp数组以及下表含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
LeetCode 509 斐波那契数列 2023.12.1
int fib(int n) {
//1确定dp数组
vector<int> vec(30 + 5);
//3数组初始化
vec[0] = 0;
vec[1] = 1;
//n<=1时直接输出不用递推公式计算
if(n <= 1)
return vec[n];
//2递推公式 4遍历顺序
for (int i = 2; i <= n ; i++)
vec[i] = vec[i-1] + vec[i-2];
//5打印得出解
return vec[n];
}
LeetCode 70 爬楼梯 2023.12.1
int climbStairs(int n) {
//1确定dp数组及其下标含义,这里下标含义为爬到n阶台阶的方法数
vector<int> dp(45+1);
//3dp数值初始化,到达第0阶方法数这里只是赋值,没用;
//到达第一阶有1种方法,到达第二阶有2种方法
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
//当n为1或2时方法数直接得出,不用递推
if(n <= 2)
return dp[n];
//2 确定递推公式 4 确定遍历顺序
//这里一定要明白:每一步都有两种选择,爬一个台阶或爬两个台阶
//所以dp[n] = dp[n-1] + dp[n-2] 表示到达n阶的方法数=爬一个台阶的方法数+爬两个台阶的方法数
for (int i = 3; i <= n; i++)
dp[i] = dp[i-1] + dp[i-2];
return dp[n];
}
LeetCode 746 使用最小花费爬楼梯 2023.12.1
int minCostClimbingStairs(vector<int>& cost) {
//1确定dp数组,并确定下标含义,这里下标是指到达该位置所花费用
vector<int> dp(1005);
//3 数组初始化,这里只需初始化第0台阶和第1台阶花费为0
dp[0] = 0;
dp[1] = 0;
//2 确定递推公式 4 确定遍历顺序
//到达i阶台阶的费用 = min(到达i-2阶费用+从i-2阶上的费用,到达i-1阶费用+从i-1阶上的费用)
for (int i = 2; i <= cost.size(); i++)
dp[i] = min(dp[i-2]+cost[i-2], dp[i-1]+cost[i-1]);
//最后的顶是第cost.size()阶
return dp[cost.size()];
}