链接:
979. 在二叉树中分配硬币
题意:
一个二叉树,n个节点,节点权值总和为n,每次可以相邻节点间移动1权值
求让每个节点都为1的最少次数
解:
给定了一个树的结构体,先整一手DFS/BFS,n不大,随便莽莽
首先每个节点只需要剩下1,而且可以知道叶子节点如果不为1,肯定要通过父节点移动
所以只要预设该叶子结点为1,所需要的代价转移到父节点身上,就可以将该叶子结点从树中抹去(因为已经处理完毕)
分析以下几种情况:
1.该叶子结点值为1:由于是叶子结点,且数量正好,所以发生移动的可能性为0,代表这个叶子节点已经处理完毕,可以从树中抹去不在考虑
2.该叶子结点值小于1:由于具有唯一的来源(父节点)所以可以进行代价转移,先花费1-val次移动次数,同时使父节点的值减少1-val,而后将自身抹去,因为不再参与移动(由于父节点可能为0,减少后存在负数,方便理解,使用权值表示而不是金币)
3.该叶子结点值大于1:由于具有唯一的去向(父节点)所以可以进行代价转移,先花费val-1次移动次数,将多余权值全部给予父节点,而后将自身抹去,因为不再参与移动
4.当所有叶子结点从树中抹去,则原先它们的父节点称为新的叶子结点,在进行前面三种情况的处理。
5.最后只剩根节点的时候,由于权值总和为n,当每个节点为1的时候才抹去,则处理到根节点时值一定为1
实际代码:文章来源:https://www.toymoban.com/news/detail-561050.html
#include<bits/stdc++.h>
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
void add(vector<int> &temp,TreeNode *root,int mao)//建树
{
root->val=temp[mao-1];
if( mao*2-1<temp.size() && temp[mao*2-1]!=-1)//left child add
{
root->left=new TreeNode;
add(temp,root->left,mao*2);
}
if( mao*2<temp.size() && temp[mao*2]!=-1)//right child add
{
root->right=new TreeNode;
add(temp,root->right,mao*2+1);
}
}
void solve(TreeNode* now,int &ans,TreeNode* father)
{
if(now->left!=nullptr) solve(now->left,ans,now);//DFS
if(now->right!=nullptr) solve(now->right,ans,now);//DFS
//if(father==nullptr) return;
//最后只剩根节点的时候,由于权值总和为n,当每个节点为1的时候才抹去,则处理到根节点时值一定为1
//cout<<now->val<<" "<<ans<<endl;
if(now->val<1 && father!=nullptr)
{
ans+= 1-now->val;//计算移动次数
father->val-= 1-now->val;//代价转移
now->val=1;//设为1
}
if(now->val>1 && father!=nullptr)
{
ans+= now->val-1;//计算移动次数
father->val+= now->val-1;//代价转移
now->val=1;//设为1
}
}
int distributeCoins(TreeNode* root)
{
int ans=0;
solve(root,ans,nullptr);
return ans;
}
int main()
{
int n;cin>>n;
vector<int> temp;TreeNode root;
for(int i=1;i<=n;i++)
{
int t;cin>>t;temp.push_back(t);
}
add(temp,&root,1);//建树
int ans=distributeCoins(&root);
cout<<ans<<endl;
return 0;
}
限制:文章来源地址https://www.toymoban.com/news/detail-561050.html
- 树中节点的数目为
n
1 <= n <= 100
0 <= Node.val <= n
- 所有
Node.val
的值之和是n
到了这里,关于2023-07-14力扣每日一题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!