1518. 换酒问题
小区便利店正在促销,用 numExchange 个空酒瓶可以兑换一瓶新酒。你购入了 numBottles 瓶酒。
如果喝掉了酒瓶中的酒,那么酒瓶就会变成空的。
请你计算 最多 能喝到多少瓶酒。
分析
第一轮喝numBottles ,然后再喝[numBottles /numExchange ]的酒,产生[numBottles /numExchange ]+numBottles %numExchange 的空瓶…直到空瓶的个数小于numExchange 就直接返回了
模拟
class Solution {
public:
int numWaterBottles(int numBottles, int numExchange) {
int res=numBottles;
int blank=numBottles;
while(blank>=numExchange){
res+=blank/numExchange;
blank=blank/numExchange+blank%numExchange;
}
return res;
}
};
1519. 子树中标签相同的节点数
给你一棵树(即,一个连通的无环无向图),这棵树由编号从 0 到 n - 1 的 n 个节点组成,且恰好有 n - 1 条 edges 。树的根节点为节点 0 ,树上的每一个节点都有一个标签,也就是字符串 labels 中的一个小写字符(编号为 i 的 节点的标签就是 labels[i] )
边数组 edges 以 edges[i] = [ai, bi] 的形式给出,该格式表示节点 ai 和 bi 之间存在一条边。
返回一个大小为 n 的数组,其中 ans[i] 表示第 i 个节点的子树中与节点 i 标签相同的节点数。
树 T 中的子树是由 T 中的某个节点及其所有后代节点组成的树。
分析
状态表示:f(root,a)表示以root根节点中a字符的个数
状态转移:f(root,a)=f(son,a)+当前节点字符是否为a
代码思路:建立邻接矩阵,初始化,深搜完善f数组,f中拿取一部分输出
深搜过程:当前节点的符合元素+1,接着遍历所有儿子节点,因为是无向图所以加个判断,然后继续深搜,到底了就按照转移方程来
树形dp+dfs
class Solution {
public:
vector<vector<int>> g;
vector<vector<int>> f;
void dfs(int curr,int father,string& labels){
f[curr][labels[curr]-'a']=1;
for(auto son:g[curr]){
if(son==father)
continue;
dfs(son,curr,labels);
for (int i = 0; i < 26; ++i) {
f[curr][i] += f[son][i];
}
}
}
vector<int> countSubTrees(int n, vector<vector<int>>& edges, string labels) {
g.resize(n);
for(auto edge:edges){
int a=edge[0];
int b=edge[1];
g[a].push_back(b);
g[b].push_back(a);
}
f.assign(n, vector<int>(26));
dfs(0,-1,labels);
vector<int> res;
for(int i=0;i<n;i++){
res[i]=f[i][labels[i]-'a'];
}
return res;
}
};
·