404. Sum of Left Leaves的C++解法

本文介绍了一种计算二叉树中所有左叶子节点值之和的方法,提供了两种实现方式:一种是使用队列的广度优先搜索,另一种是采用递归算法。递归算法更简洁且效率更高。

广度优先遍历,只判断左子树是不是叶子,是的话求和。

class Solution {
public:
	int sumOfLeftLeaves(TreeNode* root) {
		if (root == NULL) return 0;
		else{
			queue<TreeNode*> q;
			q.push(root);
			int sum = 0;
			while (!q.empty())
			{
				TreeNode* p = q.front();
				q.pop();
				if (p->left != NULL)
				{
					q.push(p->left);
					if ((p->left->left == NULL) && (p->left->right == NULL))
						sum = sum + p->left->val;
				}
				if (p->right != NULL)
					q.push(p->right);
			}
			return sum;
		}		
	}
};

最优解给的是递归算法。

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if (!root) return 0;
        if (root->left && !root->left->left && !root->left->right) return root->left->val + sumOfLeftLeaves(root->right);
        return sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
    }
};


C++解决下列问题,时限为1s,保证通过给定的样例,代码尽量不使用STL,变量名简短使用小写字母,使用正常普通的数组,数组下标尽量从1开始,代码实现尽量简洁思路清晰,不压行: 题目描述 袋子里有n条木棍,长度为a[1],a[2],…,a[n] 重复一下操作m次: ·从袋子里拿出一根最长的棍子,把它平均折成两半,然后把两根棍子都放回袋子里 求经过m次操作后,袋子里第k大的木棍长度 有t组数据 输入格式 第一行一个整数t,表示数据组数 下面有t组数据,每组数据是以下格式: 第一行三个整数n,m,k 下面一行n个数a[1],…,a[n] 输出格式 对于每组数据输出一行一个数代表答案,精度至少为10^(-10) 样例 输入 2 3 4 5 40 20 30 10 100 50 1 2 3 4 5 6 7 8 9 10 输出 10.00000000000000000000 0.50000000000000000000 数据范围 ·1≤t≤100000 ·1≤n≤100000 ·1≤a[i]≤1000000000 ·1≤m≤1000000000 ·1≤k≤n+m 下面是代码,有问题样例答案错误,请修订: #include <iostream> #include <queue> #include <map> #include <cmath> #include <iomanip> using namespace std; typedef long long ll; typedef pair<double, ll> pdl; const double eps = 1e-10; double mx; ll n, m, k, t; ll f(double x, vector<double>& a) { ll cnt = 0; for (double len : a) { if (len >= x) cnt++; } if (x <= eps) return n + m; priority_queue<pdl> pq; map<double, ll> freq; for (double len : a) { if (len > 0) { freq[len]++; } } for (auto it : freq) { pq.push({it.first, it.second}); } ll cnt1 = 0, cnt2 = 0; ll op_left = m; while (!pq.empty() && op_left > 0) { double len = pq.top().first; ll count = pq.top().second; pq.pop(); if (len < x) break; ll ops = min(count, op_left); if (len >= 2*x) { cnt1 += ops; } else if (len >= x) { cnt2 += ops; } op_left -= ops; double new_len = len / 2; if (new_len >= x) { if (freq.find(new_len) != freq.end()) { freq[new_len] += 2*ops; } else { freq[new_len] = 2*ops; pq.push({new_len, freq[new_len]}); } } } return cnt + cnt1 - cnt2; } int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> t; while (t--) { cin >> n >> m >> k; vector<double> a(n); mx = 0; for (int i = 0; i < n; i++) { cin >> a[i]; if (a[i] > mx) mx = a[i]; } double l = 0, r = mx; while (r - l > eps) { double mid = (l + r) / 2; if (f(mid, a) >= k) { l = mid; } else { r = mid; } } cout << fixed << setprecision(20) << l << '\n'; } return 0; }
09-21
在求二叉树左叶子节点之和的代码中,使用 `if (root->left && !root->left->left && !root->left->right)` 这个条件语句是为了准确判断一个节点是否为左叶子节点。左叶子节点的定义是该节点是其父节点的左子节点,并且自身没有左右子节点。这个条件语句正是用来筛选出满足这一条件的节点,从而将其值累加到左叶子节点之和中。 而求右叶子之和时,由于右叶子节点与左叶子节点的判断逻辑不同,所以不能直接使用这个条件语句。右叶子节点的定义是该节点是其父节点的右子节点,并且自身没有左右子节点。因此,判断右叶子节点需要使用类似的条件语句,但要针对右子节点进行判断,例如 `if (root->right && !root->right->left && !root->right->right)`。 以下是一个求二叉树左叶子节点之和与右叶子节点之和的示例代码: ```cpp #include <iostream> // 定义二叉树节点结构 struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; // 求左叶子节点之和 int sumOfLeftLeaves(TreeNode* root) { if (!root) return 0; int leftSum = 0; if (root->left && !root->left->left && !root->left->right) { leftSum = root->left->val; } leftSum += sumOfLeftLeaves(root->left); leftSum += sumOfLeftLeaves(root->right); return leftSum; } // 求右叶子节点之和 int sumOfRightLeaves(TreeNode* root) { if (!root) return 0; int rightSum = 0; if (root->right && !root->right->left && !root->right->right) { rightSum = root->right->val; } rightSum += sumOfRightLeaves(root->left); rightSum += sumOfRightLeaves(root->right); return rightSum; } int main() { // 创建一个简单的二叉树 TreeNode* root = new TreeNode(1); root->left = new TreeNode(2); root->right = new TreeNode(3); root->left->left = new TreeNode(4); root->right->right = new TreeNode(5); int leftSum = sumOfLeftLeaves(root); int rightSum = sumOfRightLeaves(root); std::cout << "Left leaves sum: " << leftSum << std::endl; std::cout << "Right leaves sum: " << rightSum << std::endl; // 释放内存 delete root->left->left; delete root->left; delete root->right->right; delete root->right; delete root; return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值