算法训练营day37_贪心算法(3.9)
738.单调递增的数字
首先暴力肯定是超时的,A不了;
首先特判一下是不是全都是一样的数,直接输出原数;(因为后面的逻辑是判断当前数跟下一个数,怕影响,就先特判了)
可以转变为字符串,从高位往低位走;
- 如果当前位>下一位,当前位-1,之后的位都是9;
- 如果当前位=下一位,还要判断一串相等的数后面的数大还是小,如果小,那么当前位-1,之后的位都是9,如果大,那么不操作;
- 否则就直接取数,不操作;
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string t=to_string(n);
int ans=0;
int len=t.size();
bool flag=true;
for(int i=1;i<len;i++){
if(t[i]!=t[0]){
flag=false;
break;
}
}
if(flag) return n;
for(int i=0;i<len;i++){
if(i!=len-1&&t[i]>t[i+1]){
ans=ans*10+t[i]-'0'-1;
for(int cnt=0;cnt<len-1-i;cnt++){
ans=ans*10+9;
}
break;
}
if(i!=len-1&&t[i]==t[i+1]){
int j=i+1;
while(j<len&&t[j]==t[i]) j++;
if(t[j]>t[i]){
ans=ans*10+t[i]-'0';
continue;
};
ans=ans*10+t[i]-'0'-1;
for(int cnt=0;cnt<len-1-i;cnt++){
ans=ans*10+9;
}
break;
}
ans=ans*10+t[i]-'0';
}
return ans;
}
};
随想录思路:
若当前>下一位,当前-1,下一位变为9;(有可能后面一串相等的,这些也要变,所以记录一下变9的后面都要变9);
倒序遍历,可以保证后面迭代的结果可以用在前面;(倒序遍历很关键)
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string t=to_string(n);
int len=t.size();
int flag=len;
for(int i=len-1;i>=1;i--){
if(t[i-1]>t[i]){
flag=i;
t[i-1]--;
}
}
for(int i=flag;i<len;i++){
t[i]='9';
}
int ans=stoi(t);
return ans;
}
};
968. 监控二叉树
这道题挺难的,周赛2124分的题;
我的思路wa了,只过了一半(正确思路wa了之后看出来了,不知道咋实现,还想着单节点操作下面两层。。。没实现);
我的(错误)思路
叶子节点的父亲必装;
只要儿子都装了,自己就不用装;
有一个没装,自己就要装;
//wa一半代码
class Solution {
public:
int ans;
bool dfs(TreeNode* u){
if(u->left==NULL&&u->right==NULL) return false;
if(u->left!=NULL&&u->right==NULL){
if(dfs(u->left)) return false;
}
if(u->left==NULL&&u->right!=NULL){
if(dfs(u->right)) return false;
}
if(u->left!=NULL&&u->right!=NULL){
bool flag1=dfs(u->left);
bool flag2=dfs(u->right);
if(flag1&&flag2) return false;
}
ans++;
return true;
}
int minCameraCover(TreeNode* root) {
ans=0;
if(root->left==NULL&&root->right==NULL) return 1;
dfs(root);
return ans;
}
};
正确思路:
尽量让每个灯都处于中间的位置(可辐射到父亲,孩子),叶子结点的父亲要装;
考虑节点的状态,三个,0未覆盖,1放摄像头,2没放摄像头但被覆盖;
- 如果存在孩子为未覆盖0,则返回1放摄像头;
- 如果存在孩子为摄像头1,则返回2没放但被覆盖;
- 如果孩子都是2没放摄像头但被覆盖,则返回0未覆盖(开启新的”叶子节点“,让自己父亲放);
因此,为了让叶子节点的父亲放,空结点返回2,让叶子节点为1;
还要考虑最后的根节点,根节点也会返回值,如果为0代表未被覆盖,需要放;如果为1,2说明被覆盖了;
class Solution {
public:
int ans;
int dfs(TreeNode* u){
if(u==NULL) return 2;
int flag1=dfs(u->left);
int flag2=dfs(u->right);
if(flag1==0||flag2==0){
ans++;
return 1;
}
if(flag1==1||flag2==1) return 2;
return 0;
}
int minCameraCover(TreeNode* root) {
ans=0;
if(dfs(root)==0) ans++;
return ans;
}
};