算法Day37 | 738.单调递增的数字, 968.监控二叉树,贪心总结

738.单调递增的数字

题目链接: 738.单调递增的数字
对于char进行减法时,想要通过数字相减再转化为对应的字符,需要再加上个’0’

char a = '9';
char b = a - '1';//error
char c = a - '1' + '0';

a--;//满足要求
class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        string s = to_string(n);
        int flag = s.size();//记录从哪开始都是9
        for (int i = s.size() - 1; i > 0; --i) {
            if (s[i - 1] > s[i]) {
                s[i - 1]--;//直接在s上修改
                flag = i;
            }
        }
        for (int i = flag; i < s.size(); ++i) {
            s[i] = '9';
        }
        return stoi(s);
    }
};

968.监控二叉树

题目链接:968.监控二叉树
贪心策略:优先在叶子节点的父节点放置摄像头,然后每两个节点放置一个摄像头,往根节点推。
从根节点开始出发,因此采用后序遍历。
每个节点可分为三个状态:无覆盖0、有摄像头1和有覆盖2无覆盖有摄像头+有覆盖是互斥事件)。
还要考虑一下空节点(因为在递归的终止条件是对空节点的判断),为了满足贪心策略,空节点只能是有覆盖2

节点状态转移,有以下情况:

  • 左、右孩子都为有覆盖2,则父节点为无覆盖0
  • 左、右孩子至少有一个为无覆盖0,则父节点为有摄像头1
  • 左、右孩子至少有一个为有摄像头1,则父节点为有覆盖2

最终所有节点不能是无覆盖0状态。
特殊情况:所以当第一种情况发生时,该情况下的父节点为根节点时,需要将根节点设置为有摄像头1
第二种情况也包含无覆盖0,但是当父节点为有摄像头1时,已经去掉了无覆盖0状态。
上述三种情况中,第二条和第三条是有严格的优先顺序,当第二条执行完毕,第三条的条件就为左右孩子一定不是无覆盖的前提下再判断。

class Solution {
    int res = 0;
    int/*返回状态*/ recursive(TreeNode* cur) {
        if (!cur) return 2;//终止条件
        int left = recursive(cur->left);//左
        int right = recursive(cur->right);//右
        //中
        if (left == 2 && right == 2) return 0;//情况一
        if (left == 0 || right == 0) {//情况二
            ++res;
            return 1;
        }
        if (left == 1 || right == 1) return 2;//情况三
        return -1;//与题意无关,满足非空返回函数,当其他条件都不满足时,需要有返回值
    }
public:
    int minCameraCover(TreeNode* root) {
        if (recursive(root) == 0/*特殊情况*/)
            ++res;
        return res;
    }
};

对于return -1;语句说明的是,根据设计逻辑上不可能执行到该语句。但因为编程语言为了满足if的完整性,从而要求的,可以将该语句改为else return -1;,从而满足了if的完整性。
或者可以将这一判断中的三个if整合为

if (left == 2 && right == 2) //情况一
	return 0;
else if (left == 0 || right == 0) {//情况二
	++res;
	return 1;
} else //情况三
	return 2;

也可以满足if完整性,可以省略掉return -1。但是代码可读性差。


总结

主要还是看局部贪心策略的选取吧,是否能推到全局最优,而且没有明显的反例,试一下,如果通过了,证明策略满足要求。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值