day37打卡
738. 单调递增的数字
解法,贪心:
从后向前遍历,找出并记录最终递减的位置,把当前减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);//记录从哪开始进行的赋值9int 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);}
};
968. 监控二叉树
解法,贪心:局部最优:让叶子节点的父节点安摄像头,所用摄像头最少 -》整体最优:全部摄像头数量所用最少!
先给叶子节点父节点放个摄像头,然后隔两个节点放一个摄像头,直至到二叉树头结点。
这个思路就是我们的后序遍历二叉树。
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;//无意义,}
};