第五節:二叉樹相關(反轉二叉樹[遞歸/棧]、最大路徑和)

一. 反轉二叉樹

一. 題目描述

    給你一棵二叉樹的根節點 root ,反轉這棵二叉樹,並返回其根節點。

    示例:

    leetcode:https://leetcode.cn/problems/invert-binary-tree/description/

    難度:【簡單】

二. 思路分析1-遞歸

 1. 首先要有遞歸結束的條件

 2. 先寫出來第一次運行的代碼,然後將相應的位置改爲遞歸調用即可


class TreeNode {
	val: number;
	left: TreeNode | null;
	right: TreeNode | null;
	constructor(val: number, left?: TreeNode | null, right?: TreeNode | null) {
		this.val = val === undefined ? 0 : val;
		this.left = left === undefined ? null : left;
		this.right = right === undefined ? null : right;
	}
}

function invertTree(root: TreeNode | null): TreeNode | null {
	//非空判斷
	if (root === null) return null;

	//第一次代碼
	// let leftNode = root.left;
	// root.left = root.right;
	// root.right = leftNode;

	//遞歸反轉
	let leftNode = root.left;
	root.left = invertTree(root.right);
	root.right = invertTree(leftNode);

	return root;
}

 

三. 思路分析-棧

1. 聲明棧,默認root入棧

2. while循環,棧中有數據

      A. 出棧,左右子節點交換(都爲null,不操作)

      C. 左右子節點不爲null,則入棧


function invertTree(root: TreeNode | null): TreeNode | null {
	//1.非空判斷
	if (root === null) return null;

	//2.聲明棧結構(數組模擬)
	let stack = [root];

	//3.遍歷棧結構,進行反轉交換
	while (stack.length > 0) {
		//3.1 出棧
		let current = stack.pop()!;

		//3.2 左右子節點交換位置
		//左右都爲null, 不進行任何操作 (相當於null null 不需要進行交換,一個優化點)
		if (current.left !== null || current.right !== null) {
			let temp = current.left;
			current.left = current.right;
			current.right = temp;
		}

		//3.3 繼續將節點入棧
		if (current.left) stack.push(current.left);
		if (current.right) stack.push(current.right);
	}

	return root;
}

 

二. 最大路徑和

一. 題目描述

     二叉樹中的 路徑 被定義爲一條節點序列,序列中每對相鄰節點之間都存在一條邊。同一個節點在一條路徑序列中 至多出現一次 。該路徑 至少包含一個 節點,且不一定經過根節點。

     路徑和:是路徑中各節點值的總和。

     給你一個二叉樹的根節點 root ,返回其 最大路徑和

     示例:

     leetcode:https://leetcode.cn/problems/binary-tree-maximum-path-sum/description/

     難度:【困難】

 

二. 思路分析

1. 核心點

     對於任意一個節點來說(不算父節點的情況下),可以獲取到的最大路徑和一定是:

     nodeMax=node.value + 左子樹能提供的最大值 + 右子樹能提供的最大值   (沒有左右子樹, 按照0計算)

2. 是不是缺失考慮父節點的情況呢?

    沒有, 因爲在去考慮父節點的左右子樹的時候,自然就將左右子節點的父節點考慮進去了

三. 代碼實操


class TreeNode {
	val: number;
	left: TreeNode | null;
	right: TreeNode | null;
	constructor(val: number, left?: TreeNode | null, right?: TreeNode | null) {
		this.val = val === undefined ? 0 : val;
		this.left = left === undefined ? null : left;
		this.right = right === undefined ? null : right;
	}
}

/**
 * 求最大路徑和
 * @param root 根節點
 * @returns 最大路徑的和
 */
function maxPathSum(root: TreeNode | null): number {
	let maxSum = -Infinity; //負無窮大

	//定義內部函數,進行遞歸操作
	function dfs(node: TreeNode | null): number {
		if (!node) return 0;

		//左右子樹計算可以提供的非0最大值
		const leftSum = Math.max(dfs(node.left), 0);
		const rightSum = Math.max(dfs(node.right), 0);

		//當前節點能獲得到的最大值
		const pathSum = node.val + leftSum + rightSum;
		maxSum = Math.max(pathSum, maxSum);

		//返回當前節點中能獲取的最大值
		return node.val + Math.max(leftSum, rightSum);
	}

	//調用遞歸
	dfs(root);

	return maxSum;
}

 

 

三. 

 

 

 

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鵬飛)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 聲     明1 : 如有錯誤,歡迎討論,請勿謾罵^_^。
  • 聲     明2 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章