143、【回溯算法】leetcode ——738. 单调递增的数字:暴力法+贪心法(C++版本)
题目描述
原题链接:738. 单调递增的数字
解题思路
(1)暴力法
以此遍历对比。对比方式是用当前末尾和上一个末尾的数对比,初始化时,让上一个记录末尾的数为10,从而可实现从最后一个位数的数,对比到第一个位数的数。
class Solution {
public:
bool checkNum(int num) {
int maxNum = 10; // 第一个数先和10比,从而让每个数能按逻辑和前一个数比
while(num) {
int t = num % 10; // 获取末尾位数的数值
if(maxNum >= t) maxNum = t; // 和前一位比比前一位小,继续向下比,大于则false
else return false;
num /= 10; // 除10
}
return true;
}
int monotoneIncreasingDigits(int n) {
for(int i = n; i > 0; i--) {
if(checkNum(i)) {
return i;
}
}
return 0;
}
};
时间复杂度:
O
(
n
∗
m
)
O(n*m)
O(n∗m)
空间复杂度:
O
(
1
)
O(1)
O(1)
暴力法会报错。
(2)贪心算法
根据位数之间的关系,当num[i - 1] > num[i]时,例如:78,此时从77-70都不满足题中条件,而最大可满足条件的数则是69,具体操作是让num[i]=9,再让num[i - 1]–实现。
根据上述规律,我们可以先将数字按位变成字符变成可对比的模式,设置一个变量flag
记录变为9的最高位,然后从后往前依次遍历对比。
局部最优: 遇到strNum[i - 1] > strNum[i]的情况,让strNum[i - 1]–,然后strNum[i]给为9,可以保证这两位变成最大单调递增整数。
全局最优: 得到小于等于N的最大单调递增的整数。
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string strNum = to_string(n);
int flag = strNum.size(); // flag标记变9的位置
for(int i = strNum.size() - 1; i > 0; i--) {
if(strNum[i - 1] > strNum[i]) { // 前一位比后一位大
flag = i; // 后一位变为9
strNum[i - 1]--; // 前一位的位数减一
}
}
for(int i = flag; i < strNum.size(); i++) { // 从flag往后变9
strNum[i] = '9';
}
return stoi(strNum);
}
};
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
参考文章:738.单调递增的数字
相关文章
- C++面向对象编程解决三阶矩阵相加减
- leetcode 10 正则表达式匹配(c++)
- C语言/C++基础之火车快跑
- 深入理解C/C++ [Deep C (and C++)] (2)
- [手游项目2]-10-C++怎样关闭一个已经名称的程序的进程?
- C++学习心得与c语言到c++衔接技巧
- Leetcode 搜索旋转排序数组(执行用时: 0 ms , 在所有 C++ 提交中击败了 100.00% 的用户)
- C++语言本身没有输入输出语句
- Leetcode 两数之和 C / C++
- LeetCode 罗马数字转整数(执行用时: 16 ms , 在所有 C++ 提交中击败了 49.87% 的用户)
- C++ int转四字节数组
- c++ vector 初始化_C++--vector()的用法
- [LeetCode] 032. Longest Valid Parentheses (Hard) (C++)
- 关于C++ const 的全面总结
- C++模板中的函数式参数
- c++字符串
- 浅谈C++多态性
- C++11 智能指针
- C++ 标识符
- 【Leetcode刷题Python】 LeetCode 2038. 如果相邻两个颜色均相同则删除当前颜色
- 第十三届蓝桥杯C++B组国赛H题——机房 (AC)
- 第十三届蓝桥杯C++B组国赛E题——出差 (AC)
- 【C++ 科学计算】矩阵变量类型总结
- C/C++学习笔记十二 Input and Output (I/O)(1)
- PCL(c++)例子源码编译可执行工具完整统计