zoukankan      html  css  js  c++  java
  • 把二叉搜索树转换为累加树

    1. 题目描述

    给出二叉搜索树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点node的新值等于原树中大于或等于node.val的值之和。
    提醒一下,二叉搜索树满足下列约束条件:

    • 节点的左子树仅包含键 小于 节点键的节点。
    • 节点的右子树仅包含键 大于 节点键的节点。
    • 左右子树也必须是二叉搜索树。

    示例 1:

    输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
    输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
    

    2. 题解

    Morris遍历算法的步骤:

    1. 根据当前节点,找到其前序节点,如果前序节点的右孩子是空,那么把前序节点的右孩子指向当前节点,然后进入当前节点的左孩子。
    2. 如果当前节点的左孩子为空,打印当前节点,然后进入右孩子。
    3. 如果当前节点的前序节点其右孩子指向了它本身,那么把前序节点的右孩子设置为空,打印当前节点,然后进入右孩子。


    相关阅读:算法数据结构,如何面试进入google-51 二叉树的Morris遍历法 - YouTube

    public TreeNode convertBST(TreeNode root) {
    	int sum = 0;
    	TreeNode node = root;
    
    	while (node != null) {
    		if (node.right == null) {
    			sum += node.val;
    			node.val = sum;
    			node = node.left;
    		} else {
    			TreeNode succ = getSuccessor(node); // 后继节点
    			if (succ.left == null) {
    				succ.left = node;
    				node = node.right;
    			} else {
    				succ.left = null;
    				sum += node.val;
    				node.val = sum;
    				node = node.left;
    			}
    		}
    	}
    
    	return root;
    }
    
    public TreeNode getSuccessor(TreeNode node) {
    	TreeNode succ = node.right;
    	while (succ.left != null && succ.left != node) {
    		succ = succ.left;
    	}
    	return succ;
    }
    

    Morris遍历的关键是找前序节点,而这里把二叉搜索树转换为累加树的关键是找后继节点,方法名getSuccessor中的successor是后继者的意思。
    将当前节点的值加上后继节点的值作为当前节点的新值。
    原来节点8(这里表示值为8的节点)没有后继节点,所以节点8的新值还是8
    原来节点7的后继节点为节点8(新值),于是节点7的新值为15(7 + 8);原来节点6的后继节点为节点15(新值),于是节点6的新值为21(6 + 15),以此类推。

    参考:

  • 相关阅读:
    jinja模板语法
    flask处理cookie
    django模板语法
    django模型操作
    世间有一种坏
    单纯指望运动减肥的是几乎不可能的?
    主题
    slax自启动程序
    搞定TADA68机械键盘的固件修改
    ubuntu中编译安装gcc 9.2.0
  • 原文地址:https://www.cnblogs.com/gzhjj/p/14173530.html
Copyright © 2011-2022 走看看