题目详细:LeetCode.738
由题可知:
那么我们要解决的问题就是两个:
对于解决第一个问题:
对于解决第二个问题:
高位数字 > 低位数字
,说明这两个相邻的数字是非递增的,所以低位数字要变大,为了满足递增需求所以至少要比高位数字大 最大
数字,所以为了满足最大数字的要求,我们直接将高位数字之后的低位数字都赋值 9
就行了高位数字 - 1
,最终结果才不会大于 nJava解法(贪心):
class Solution {public int monotoneIncreasingDigits(int n) {String s = String.valueOf(n);char[] chars = s.toCharArray();int start = s.length();for (int i = s.length() - 2; i >= 0; i--) {if (chars[i] > chars[i + 1]) {chars[i]--;start = i + 1;}}for (int i = start; i < s.length(); i++) {chars[i] = '9';}return Integer.parseInt(String.valueOf(chars));}
}
这道题我想到解法后,也知道可以将数字转数组后再进行操作,但是为了尽可能的降低空间复杂度,我打算直接对n来进行操作,从低位向高位逐位获取数字并进行比较,后续思路与上述解法思路相同;
但是绞尽脑汁之后还是放弃了,因为这样操作的话,标记start就显得有些复杂了,也没有简洁的逻辑思路将其后续位置的数字都变成9,只能是从头再遍历一次数字才能得知正确结果;
而且这种解法在操作n的过程中就已出错,所以发现我是小题大做了,还是得将数字转数组后再进行操作会好理解些。
题目详细:LeetCode.968
这道题属实是直接把我CPU给烧了,不过看完题解之后很快就理解了,第一次发现原来还有状态标记和转移这种思路,详细的题解可以查阅:《代码随想录》— 监控二叉树
Java解法(贪心,后序遍历):
class Solution {private int ans = 0;public int minCameraCover(TreeNode root) {// 最后对根节点的状态做检验,如果根节点是无被覆盖状态,那么需要在根节点放置一台摄像机。if(this.dfs(root) == 0){this.ans++;}return this.ans;}/*节点的状态值:0:表示无被覆盖 1:表示有摄像头2:表示有被覆盖后序遍历:根据当前节点的左右节点的状态,来判读当前节点的状态*/public int dfs(TreeNode root){if(null == root){// 空节点默认为有覆盖状态,避免在叶子节点上放摄像头return 2;}int left = this.dfs(root.left);int right = this.dfs(root.right);if(left == 2 && right == 2){// 如果左右节点都是被覆盖状态,那么当前节点的状态就应该是无覆盖,没有摄像头return 0;}else if(left == 0 || right == 0){// 如果左右节点都是无被覆盖状态,那当前节点此时应该放一个摄像头this.ans++;return 1;}// 如果左右节点至少存在1个摄像头,说明当前节点是被覆盖的return 2;}
}
上一篇:多团队协作构建可观测性