找回密码
 立即注册
查看: 6|回复: 0

洛谷P3365 改造二叉树:从问题分析到代码实现

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 打卡月天数:4
  • 打卡总奖励:29
  • 最近打卡:2025-07-12 15:59:50

7

主题

2

回帖

2316

积分

VIP

积分
2316
发表于 6 天前 | 显示全部楼层 |阅读模式
截图未命名.jpg
一、问题分析

题目要求我们计算将二叉树修改为二叉搜索树(BST)所需的最少修改次数。二叉搜索树的性质是:对于任意节点,其左子树所有节点的值都小于该节点的值,右子树所有节点的值都大于该节点的值。

二、解题思路
  • 中序遍历序列‌:BST的中序遍历结果是一个严格递增序列
  • ‌问题转化‌:将原二叉树的中序遍历序列转换为严格递增序列所需的最少修改次数
  • ‌最长递增子序列(LIS)‌:最少修改次数 = 序列长度 - 最长递增子序列长度

三、C++代码实现
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. using namespACe std;

  5. struct TreeNode {
  6.     int val;
  7.     TreeNode *left;
  8.     TreeNode *right;
  9.     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  10. };

  11. // 构建二叉树
  12. TreeNode* buildTree(int n, const vector<int>& vals, const vector<pair<int, int>>& edges) {
  13.     vector<TreeNode*> nodes(n + 1);
  14.     for (int i = 1; i <= n; ++i) {
  15.         nodes[i] = new TreeNode(vals[i - 1]);
  16.     }
  17.    
  18.     for (int i = 2; i <= n; ++i) {
  19.         int fa = edges[i - 2].first;
  20.         int ch = edges[i - 2].second;
  21.         if (ch == 0) {
  22.             nodes[fa]->left = nodes[i];
  23.         } else {
  24.             nodes[fa]->right = nodes[i];
  25.         }
  26.     }
  27.     return nodes[1];
  28. }

  29. // 中序遍历收集节点值
  30. void inorder(TreeNode* root, vector<int>& seq) {
  31.     if (!root) return;
  32.     inorder(root->left, seq);
  33.     seq.push_back(root->val);
  34.     inorder(root->right, seq);
  35. }

  36. // 计算最长递增子序列长度
  37. int lengthOfLIS(vector<int>& nums) {
  38.     vector<int> dp;
  39.     for (int num : nums) {
  40.         auto it = lower_bound(dp.begin(), dp.end(), num);
  41.         if (it == dp.end()) {
  42.             dp.push_back(num);
  43.         } else {
  44.             *it = num;
  45.         }
  46.     }
  47.     return dp.size();
  48. }

  49. int main() {
  50.     ios::sync_with_stdio(false);
  51.     cin.tie(nullptr);
  52.    
  53.     int n;
  54.     cin >> n;
  55.    
  56.     vector<int> vals(n);
  57.     for (int i = 0; i < n; ++i) {
  58.         cin >> vals[i];
  59.     }
  60.    
  61.     vector<pair<int, int>> edges(n - 1);
  62.     for (int i = 0; i < n - 1; ++i) {
  63.         cin >> edges[i].first >> edges[i].second;
  64.     }
  65.    
  66.     TreeNode* root = buildTree(n, vals, edges);
  67.     vector<int> seq;
  68.     inorder(root, seq);
  69.    
  70.     int lis_len = lengthOfLIS(seq);
  71.     cout << n - lis_len << endl;
  72.    
  73.     return 0;
  74. }
复制代码





来源:洛谷P3365 改造二叉树:从问题分析到代码实现






您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

SEO网站 ( 冀ICP备2025113422号-2 )|网站地图

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表