算法训练营第二十三天(二叉树完结)

算法训练营第二十三天(二叉树完结)

669. 修剪二叉搜索树

力扣题目链接(opens new window)

题目

给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。

在这里插入图片描述

在这里插入图片描述

解答

自己写的递归
class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
		if (root == null)
			return null;
		if (root.val == low){
			root.left = null;
			root.right = trimBST(root.right,low,high);
		}else if (root.val == high){
			root.right = null;
			root.left = trimBST(root.left,low,high);
		}else if (root.val > low && root.val < high){
			root.left = trimBST(root.left,low,high);
			root.right = trimBST(root.right,low,high);
		}else if (root.val < low)
			root = trimBST(root.right,low,high);
		else
			root = trimBST(root.left,low,high);
		return root;
    }
}
简化递归
class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
		if (root == null)
			return null;

		if (root.val < low)
			root = trimBST(root.right,low,high);//左子树和根都不要了
		else if (root.val > high)
			root = trimBST(root.left,low,high);//右子树和根都不要了
		else {
			// root在[low,high]范围内
			root.left = trimBST(root.left,low,high);
			root.right = trimBST(root.right,low,high);
		}
		return root;
    }
}
迭代(看下图就理解了)
class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
		if(root == null)
			return null;
		// 处理头结点,让root移动到[L, R] 范围内,注意是左闭右闭
		while(root != null && (root.val < low || root.val > high)){
			if(root.val < low)
				root = root.right;// 小于L往右走
			else
				root = root.left;// 大于R往左走
		}

		TreeNode curr = root;

		// 此时root已经在[L, R] 范围内,处理左孩子元素小于L的情况
		while(curr != null){
			while(curr.left != null && curr.left.val < low){
				curr.left = curr.left.right;
			}
			curr = curr.left;
		}
		//go back to root;
		curr = root;

		// 此时root已经在[L, R] 范围内,处理右孩子大于R的情况
		while(curr != null){
			while(curr.right != null && curr.right.val > high){
				curr.right = curr.right.left;
			}
			curr = curr.right;
		}
		return root;
    }
}

在这里插入图片描述

108.将有序数组转换为二叉搜索树

力扣题目链接(opens new window)

题目

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:

在这里插入图片描述

解答

使用新的空间
class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
		if (nums.length == 0)
			return null;
		int midIndex = nums.length / 2;
		TreeNode root = new TreeNode(nums[midIndex]);
		root.left = sortedArrayToBST(Arrays.copyOfRange(nums,0,midIndex));
		root.right = sortedArrayToBST(Arrays.copyOfRange(nums,midIndex + 1,nums.length));
		return root;
    }
}
使用索引(左闭右开)
class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
		return sortedArrayToBST(nums, 0, nums.length);
    }
	//左闭右开
	public TreeNode sortedArrayToBST(int[] nums, int left, int right) {
		if (left >= right) {
			return null;
		}
		if (right - left == 1) {
			return new TreeNode(nums[left]);
		}
		int mid = left + (right - left) / 2;
		TreeNode root = new TreeNode(nums[mid]);
		root.left = sortedArrayToBST(nums, left, mid);
		root.right = sortedArrayToBST(nums, mid + 1, right);
		return root;
	}
}

538.把二叉搜索树转换为累加树

力扣题目链接(opens new window)

题目

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(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:

  • 输入:root = [0,null,1]
  • 输出:[1,null,1]

示例 3:

  • 输入:root = [1,0,2]
  • 输出:[3,3,2]

示例 4:

  • 输入:root = [3,2,4,1]
  • 输出:[7,9,4,10]

提示:

  • 树中的节点数介于 0 和 104 之间。
  • 每个节点的值介于 -104 和 104 之间。
  • 树中的所有值 互不相同 。
  • 给定的树为二叉搜索树

解答

  • 采取中序遍历,不过是右中左,相当于从最大到最小遍历
  • 对于每一个结点,他的值都等于他之前遍历的所有的值的和
  • 下面的sum其实也相当于双指针中的pre,初始状态pre指向空,cur指向最右侧结点
递归
class Solution {
	int sum = 0;
    public TreeNode convertBST(TreeNode root) {
		travel(root);
		return root;
    }

	private void travel(TreeNode root){
		if (root == null)
			return;
		//右中左
		travel(root.right);

		root.val += sum;
		sum = root.val;

		travel(root.left);
	}
}
//不好理解
class Solution {
    public TreeNode convertBST(TreeNode root) {
		travel(root,0);
		return root;
    }

	private int travel(TreeNode root,int sum){
		if (root == null)
			return sum;
		//右中左
		root.val += travel(root.right,sum);
		return travel(root.left,root.val);//每次执行完都是为下一轮做准备
	}
}
迭代
class Solution {
    public TreeNode convertBST(TreeNode root) {
		//右中左
		Stack<TreeNode> stack = new Stack<>();
		int sum = 0;
		TreeNode cur = root;
		//右中左
		while (!stack.isEmpty() || cur != null){
			while (cur != null){
				stack.push(cur);
				cur = cur.right;
			}
			cur = stack.pop();
			cur.val += sum;
			sum = cur.val;
			cur = cur.left;
		}
		return root;
    }
}

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-04-12 01:52:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-12 01:52:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-12 01:52:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-12 01:52:02       18 阅读

热门阅读

  1. 蓝桥杯——分糖果

    2024-04-12 01:52:02       15 阅读
  2. Esilnt使用记录

    2024-04-12 01:52:02       13 阅读
  3. 【IC前端虚拟项目】SDC文件编写与DC综合环境组织

    2024-04-12 01:52:02       14 阅读
  4. 钩子函数和副作用

    2024-04-12 01:52:02       13 阅读
  5. jquery 数字金额转化为大写金额

    2024-04-12 01:52:02       14 阅读
  6. 从企业开发流程到使用场景解析 git vs svn

    2024-04-12 01:52:02       16 阅读
  7. Android app如何禁止运行在模拟器中

    2024-04-12 01:52:02       16 阅读
  8. Python编程学院:揭秘面向对象的魔法

    2024-04-12 01:52:02       12 阅读
  9. 线程池使用

    2024-04-12 01:52:02       12 阅读