改造二叉树(lis+中序遍历)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=1e5+10;
int n,cnt,num[maxn],len,a[maxn],fa[maxn],l[maxn],r[maxn],dp[maxn];
void dfs(int x){
    if(x==0) return ;
    dfs(l[x]);
    num[++cnt]=a[x];
    dfs(r[x]);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    int x,y;
    for(int i=2;i<=n;i++){
        scanf("%d%d",&x,&y); fa[i]=x;
        if(y==0) l[x]=i;
        else r[x]=i;
    }
    dfs(1);
    for(int i=1;i<=cnt;i++) num[i]-=i;
    for(int i=1;i<=cnt;i++){
        if(num[i]>dp[len]) dp[++len]=num[i];
        else dp[lower_bound(dp+1,dp+1+len,num[i])-dp]=num[i];
    }
    cout<<n-len<<endl;
    return 0;
}
### 平衡二叉树中最长递增子序列算法 对于平衡二叉树中的最长递增子序列问题,通常涉及两个主要方面:一是遍历二叉树获取节点值;二是应用动态规划或其他高效算法来查找这些值构成的最长递增子序列。 #### 动态规划解决方案 当处理非线性的数据结构如二叉树时,可以先通过前序、中序或后序等方式遍历整棵树并将所有结点存储起来形成列表。之后针对此列表执行标准的一维数组形式下的LIS计算逻辑[^1]: ```python def longest_increasing_subsequence(nums): if not nums: return 0 dp = [1]*len(nums) for i in range(1, len(nums)): for j in range(i): if nums[i] > nums[j]: dp[i] = max(dp[i], dp[j]+1) return max(dp) if dp else 0 ``` 然而这种方法效率较低(O(n^2)),并不适用于大型数据集。为了提高性能,在某些情况下可以通过引入辅助的数据结构比如栈或者利用二分查找技术优化至O(n log n)。 #### 结合二叉树特性的改进方案 考虑到题目特别指出是在**平衡二叉树**内操作,则可尝试更高效的策略。由于AVL树/红黑树等自调整型BST具备较好的访问特性,允许快速定位相邻元素之间的关系,因此可以直接基于树形结构设计专门用于此类场景下的LIS算法。 具体来说,可以从根部出发向左右两侧分别探索可能存在的上升链路,并记录下当前最佳结果。这里需要注意的是要区分父子间是否存在严格意义上的增长趋势(即左孩子<父亲<右孩子),只有满足条件才能计入有效长度统计之中[^3]。 下面给出一段Python伪代码表示这一过程: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def dfs(node, prev_val, increasing=True): if node is None or (increasing and node.val <= prev_val) or (not increasing and node.val >= prev_val): return 0 l_len = dfs(node.left , node.val, True ) + 1 # 左侧递增方向 r_len = dfs(node.right, node.val, False) + 1 # 右侧递减方向 global_max[0] = max(global_max[0], l_len+r_len-1) return max(l_len,r_len) global_max=[float('-inf')] dfs(root,-float('inf')) print(max(global_max)) ``` 这段程序实现了对给定平衡二叉树最长达单调路径长度的查询功能,其中既包含了向上也向下两种可能性。注意这里的`prev_val`参数用来传递父节点数值以便判断是否形成了有效的连续序列。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值