day37打卡
解法,贪心:
从后向前遍历,找出并记录最终递减的位置,把当前减1,再把后面的全置为9即可。
举个例子,数字:332,从前向后遍历的话,那么就把变成了329,此时2又小于了第一位的3了,真正的结果应该是299。
class Solution {
public:
int monotoneIncreasingDigits(int n) {
// n是个位数就直接返回
if(n < 10) return n;
//变成字符串好操作
string nStr = to_string(n);
//记录从哪开始进行的赋值9
int flag = nStr.size();
//从后向前遍历,找出了递减的位置
for(int i = nStr.size()-1; i > 0; i--)
{
if(nStr[i-1] > nStr[i])
{
flag = i;
nStr[i-1]--;
}
}
//开始赋值‘9’
for(int i = flag; i < nStr.size(); i++)
{
nStr[i] = '9';
}
return stoi(nStr);
}
};
解法,贪心:局部最优:让叶子节点的父节点安摄像头,所用摄像头最少 -》整体最优:全部摄像头数量所用最少!
先给叶子节点父节点放个摄像头,然后隔两个节点放一个摄像头,直至到二叉树头结点。
这个思路就是我们的后序遍历二叉树。
class Solution {
// 定义三种状态:
// 0 未覆盖
// 1 已覆盖
// 2 已安装
public:
int ret = 0;
int minCameraCover(TreeNode* root) {
if(dfs(root) == 0) ret++;
return ret;
}
int dfs(TreeNode* root)
{
//如果为空,为了正确返回ret,设置为已覆盖
if(root == nullptr) return 1;
int left = dfs(root->left);
int right = dfs(root->right);
//如果两个节点都没有被覆盖,只能安装摄像头了
if(left == 0 || right == 0)
{
ret++;
return 2;//安装摄像头
}
//left和right都已经被覆盖了,但是没有安装相机,所以r是待覆盖的
else if(left == 1 && right == 1)
{
return 0;//root未覆盖
}
//left或者right已经装了一个摄像头,所以root是已覆盖的
else if(left + right >= 3)
{
return 1;//已覆盖
}
return -1;//无意义,
}
};