贪心算法
738. 单调递增的数字
题意:当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。
实例:
思路:本题我最开始的思路是暴力求解:将数字倒序判断,如果该元素满足单调递增,则直接输出,很明显这个代码超时了;其次就是贪心算法:我们将数字转化为字符串,然后对其进行倒叙的判断,如果前一个元素大于后一个元素,我们就需要将前一个元素--,后一个元素变为9,这里我们用标记代替,如果这个元素不满足条件,就给一个标记,表示这个元素和后面的元素都需要设置为9
暴力求解代码:
bool IncreasNum(int n)
{
vector<int> arr;
while (n)
{
arr.push_back(n % 10);
n /= 10;
}
for (int i = 1; i<arr.size(); i++)
{
if (arr[i - 1]<arr[i])
{
return false;
}
}
return true;
}
int monotoneIncreasingDigits(int n) {
for (int i = n; i>=0; i--)
{
if (IncreasNum(i))
{
return i;
}
}
return 0;
}
贪心算法代码:
int monotoneIncreasingDigits(int n) {
string s=to_string(n);//数字变字符串
int signal=INT_MAX;//先将标记放在最外侧,等待改变
for(int i=s.size()-1;i>0;i--)
{
if(s[i-1]>s[i])//如果前一个元素大于后一个元素,不符合条件,此时后一个元素应该置9,前一个元素--
{
signal=i;
s[i-1]--;
}
}
for(int i=signal;i<s.size();i++)//如果我们的标记在字符串范围内,就说明字符串内有需要变为9的元素
{
s[i]='9';
}
return stoi(s);//字符串变数字
}
968. 监控二叉树
题意:给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
实例:
思路:本题我在3月份的时候做过,对于解题的大致思路还是有印象的。为了实现监控的最小个数,举一个简单的例子:叶子节点大部分都是成对存在的,所以我们只需要将父节点作为监控节点可以覆盖叶子节点。因此我们需要从下往上进行监控的计算。
这里我们对节点有三种状态表示:0——表示该节点没有监控覆盖,1——表示该节点是监控节点,自身也被覆盖,2——表示该节点有监控覆盖。三种节点表达方式。
后序遍历中,当检测到节点为空时,我们默认其被覆盖返回2。
其次是后序遍历的遍历思想,左节点接受的是该节点对应的数字表达状态
最后是逻辑代码,这里也是有顺序的,大体分为三种情况:
- 当左右节点都被覆盖是,即都为2的情况。这里我们注意:这两个节点只是被覆盖,并不是监控节点。此时的父节点就应该是没有被覆盖的情况,所以返回0。
- 当左右节点的任意节点没有被覆盖时,由于我们是从下往上遍历的,因此就说明之前的监控节点都没有覆盖该节点。因此为了能覆盖该节点,我们就需要将父节点设置为监控节点,此时返回1。
- 当左右节点的任意节点被设置为监控节点时,那么它们的父节点必定是被覆盖的状态,此时返回2
最后就是在遍历完所有节点后,我们的根节点还需要进行最后一次判断。如果根节点是无覆盖状态,那么我们需要再次加入一个监控,就当是单独监控根节点了
C++代码:
int count=0;
int MonitorTree(TreeNode* root)//0——表示无覆盖,1——表示该节点有监控,2——表示有覆盖
{
if(nullptr==root)//当节点为空,我们默认为其已经被覆盖
{
return 2;
}
int left=MonitorTree(root->left);//后序遍历思想,从下往上遍历
int right=MonitorTree(root->right);
if(left==2&&right==2)//左右孩子都被覆盖,那么为了监控个数最小化,父节点不会被装监控
{
return 0;
}
if(left==0||right==0)//这里只要子节点有任何一个没有被覆盖,都需要我们的父节点成为1,去覆盖这个节点
{
count++;
return 1;
}
if(left==1||right==1)//孩子为1,那么自身必须被覆盖
{
return 2;
}
return -1;
}
int minCameraCover(TreeNode* root) {
if(MonitorTree(root)==0)//这里需要对根节点再次尽心判断,如果0,表示没有覆盖,那也是需要对其进行单独覆盖的
{
count++;
}
return count;
}