day6-7算法:樹、二叉樹、二叉搜索樹

1. 題目

  1. 給定一個二叉樹,判斷其是否是一個有效的二叉搜索樹:https://leetcode-cn.com/problems/validate-binary-search-tree/
  2. 給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

2. 基本知識

樹、二叉樹、二叉搜索樹

2.1 樹

由N個點構成的一種數據結構,有一個根節點和多層的子節點組成,連接的順序都是從根節點指向孩子節點。每一個子節點都只有一個前驅節點,但一個父節點可能有多個孩子節點。

一棵普通的樹

2.2 二叉樹

二叉樹是樹的一種,它的特點是每一個節點最多隻有兩個子節點。

這是一個滿二叉樹

2.3 二叉搜索樹

它是二叉樹的一種,又叫有序二叉樹。它是指一棵空樹或者有以下性質的二叉樹。增刪查的時機複雜度爲O(logn)

  • 左子樹上所有節點的值均小於它的根節點的值
  • 右子樹上所有的節點的值均大於它的根節點的值
  • 左右子樹也分別爲小二叉搜索樹

二叉搜索樹

3. 算法題解題

3.1 給定一個二叉樹,判斷其是否是一個有效的二叉搜索樹

假設存在鏈表 1 → 2 → 3 → Ø,我們想要把它改成 Ø ← 1 ← 2 ← 3。把每個節點的next指向它的前一個節點即可。

解法1:中序遍歷法
左節點-父節點-右節點,這個遍歷順序,則判斷前一個節點的值比後一個節點的值小即可。
時間複雜度爲O(n),空間複雜度也爲O(n)

public class TreeNode {
	int val;
	TreeNode left;
	TreeNode right;

	TreeNode(int x) {
		val = x;
	}
}


public boolean isValidBST(TreeNode root) {
	
	Stack<TreeNode> stack = new Stack<TreeNode>();
	
	if (root == null) {
		return true;
	}
	
	double inorder = -Double.MAX_VALUE;
	
	while (!stack.isEmpty() || root != null) {
		while(root != null){
			stack.push(root);
			root = root.left;
		}
		
		root = stack.pop();
		
		if (root.val < inorder) {
			return false;
		}
		inorder = root.val;
		root = root.right;
	}
	return false;
}

解法2: 遞歸
分別遞歸左右子樹,一直遞歸找到左子樹的最大值,右子樹的最小值,然後把返回的值進行比較,左節點最大值小於根節點,小於右節點最小值。

public boolean isValidBST(TreeNode root) {

	return validHelper(root ,null, null);
}

public boolean validHelper(TreeNode root, Integer min, Integer max){
	
	
	if (root == null) {
		return true;
	}
	
	Integer tempVal = root.val;
	
	// 當前值和最小值比較
	if (min != null &&  tempVal <= min) return false;
	
	// 當前值和最大值比較
	if (max != null && tempVal >= max) return false;
	
	
	//遞歸循環
	//左子樹,最大值是當前節點值
	if (!validHelper(root.left, min, tempVal)) return false;
	
	//右子樹,最小值是當前節點值
	if(!validHelper(root.right, tempVal, max)) return false;
	
	return true;
	
}

3.2 給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先

tips:自己也可以是自己的祖先節點

解法1: 遞歸法

從根節點開始遍歷,如果找到其中一個節點,則 temp 標記爲1,如果找到其中一個則認爲該分支找到了。繼續遍歷另一個分支,直到left、right、temp其中兩個爲1時,則認爲找到了公共祖先。

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    recurseTree(root, p, q);
    
    return result;
}

TreeNode result;

private boolean recurseTree(TreeNode currentNode, TreeNode p, TreeNode q) {
	
	if (currentNode == null) {
		return false;
	}
	
	int left = recurseTree(currentNode.left, p, q) ? 1 : 0;
	
	int right = recurseTree(currentNode.right, p, q) ? 1 : 0;
	
	int temp= 0; 
	if (currentNode == p || currentNode == q) {
		temp = 1;
	}
	
	if (temp + left + right == 2) {
		result = currentNode;
	}
	
	if (temp + left + right > 0) {
		return true;
	}
	
	return false;
}

4. Tips

一個可以免費上傳圖片,並分享鏈接的網站

https://sm.ms/
點擊,並上傳照片。
然後,分享鏈接即可。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章