1. 程式人生 > >暴力法求二叉樹內最大路徑長度

暴力法求二叉樹內最大路徑長度

原理很簡單,二叉樹內最大的路徑的起點和終點一定是葉子。據此可以遍歷所有的葉子進行暴力求解(好好的分治法能解決的問題被我弄成這樣)

二叉樹的節點定義如下:

package cn.edu.nju.zyf.longestPathWithinABinaryTree;

public class Node {
	private String data;
	public Node parent;
	public Node leftChild;
	public Node rightChild;
	
	public Node() {
		
	}
	public Node(String str) {
		this.data = str;
	}
	
	public String getData() {
		return data;
	}
	public void setData(String data) {
		this.data = data;
	}
}

輔助類(中的資料在初始化的時候搞定)
package cn.edu.nju.zyf.longestPathWithinABinaryTree;

import java.util.ArrayList;
import java.util.List;

public class LongestPathWithinABinaryTreeUtil {
	private Node root;
	private List<Node> leaves = new ArrayList<Node>();
	private List<ArrayList<Node>> pathsFromLeafToRoot = new ArrayList<ArrayList<Node>>();
	private int longestPathBetween2Leaves = -1;
	
	public List<ArrayList<Node>> getPathsFromLeafToRoot() {
		return pathsFromLeafToRoot;
	}

	public void setPathsFromLeafToRoot(List<ArrayList<Node>> pathsFromLeafToRoot) {
		this.pathsFromLeafToRoot = pathsFromLeafToRoot;
	}

	public Node getRoot() {
		return root;
	}

	public void setRoot(Node root) {
		this.root = root;
	}

	public List<Node> getLeaves() {
		return leaves;
	}

	public void setLeaves(List<Node> leaves) {
		this.leaves = leaves;
	}

	public LongestPathWithinABinaryTreeUtil() {
		
	}
	
	public LongestPathWithinABinaryTreeUtil(Node rt) {
		this.root = rt;
		findLeaves(this.root);
		findPathsFromLeafToRoot();
		findMaxDistanceBetweenPaths();
	}
	
	
	public int findMaxDistanceBetweenPaths() {
		if(pathsFromLeafToRoot.size()>=2) {
			this.longestPathBetween2Leaves = distanceOfLeavesBetween2LeafRootPaths(pathsFromLeafToRoot.get(0), pathsFromLeafToRoot.get(1));
			for(int i = 0;i<this.pathsFromLeafToRoot.size();i++) {
				for(int j = i+1;j<this.pathsFromLeafToRoot.size();j++) {
					if(this.longestPathBetween2Leaves<distanceOfLeavesBetween2LeafRootPaths(pathsFromLeafToRoot.get(i), pathsFromLeafToRoot.get(j))) {
						this.longestPathBetween2Leaves=distanceOfLeavesBetween2LeafRootPaths(pathsFromLeafToRoot.get(i), pathsFromLeafToRoot.get(j));
					}
				}
			}
		}
		return this.longestPathBetween2Leaves;
	}
	
	public int distanceOfLeavesBetween2LeafRootPaths(List<Node> path1, List<Node> path2) {
		int sharedYoungestAncestorForPath1 = -1;
		int sharedYoungestAncestorForPath2 = -1;
		int i = path1.size()-1;
		int j = path2.size()-1;
		while(i>0&&j>0&&path1.get(i)==path2.get(j)) {
			sharedYoungestAncestorForPath1 = i;
			sharedYoungestAncestorForPath2 = j;
			i--;
			j--;
		}
		return sharedYoungestAncestorForPath1+sharedYoungestAncestorForPath2;
	}
	
	public int getLongestPathBetween2Leaves() {
		return longestPathBetween2Leaves;
	}

	public void setLongestPathBetween2Leaves(int longestPathBetween2Leaves) {
		this.longestPathBetween2Leaves = longestPathBetween2Leaves;
	}

	public void findLeaves(Node root) {
		if(root!=null&&root.leftChild==null&&root.rightChild==null) {
			leaves.add(root);
			return;
		}
		if(root!=null&&root.leftChild!=null) {
			findLeaves(root.leftChild);
		}
		if(root!=null&&root.rightChild!=null) {
			findLeaves(root.rightChild);
		}
	}
	
	public void findPathsFromLeafToRoot() {
		ArrayList<ArrayList<Node>> paths = new ArrayList<ArrayList<Node>>();
		for(int i = 0;i<leaves.size();i++) {
			ArrayList<Node> path = new ArrayList<Node>();
			for(Node j = leaves.get(i);j!=null;j = j.parent) {
				path.add(j);
			}
			paths.add(path);
		}
		this.pathsFromLeafToRoot = paths;
		
	}
}


測試用的main方法:
package cn.edu.nju.zyf.longestPathWithinABinaryTree;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Node root = new Node("zyf");
		Node son = new Node("l11");
		Node daughter = new Node("l12");
		Node grandSon = new Node("l21");
		Node grandDaughter = new Node("l22");
		root.leftChild = son;
		son.parent = root;
		root.rightChild = daughter;
		daughter.parent=root;
		son.leftChild = grandSon;
		grandSon.parent = son;
		daughter.rightChild = grandDaughter;
		grandDaughter.parent = daughter;
		
		Node asdf = new Node("asdf");
		grandDaughter.leftChild = asdf;
		asdf.parent = grandDaughter;
		
		LongestPathWithinABinaryTreeUtil util = new LongestPathWithinABinaryTreeUtil(root);
		System.out.println(util.getLeaves().size());
		System.out.println(util.getLeaves().get(0).getData());
		System.out.println(util.getPathsFromLeafToRoot().size());
		System.out.println(util.getPathsFromLeafToRoot().get(0).get(0).getData());
		System.out.println(util.getPathsFromLeafToRoot().get(0).get(1).getData());
		System.out.println(util.getPathsFromLeafToRoot().get(0).get(2).getData());
		System.out.println(util.distanceOfLeavesBetween2LeafRootPaths(util.getPathsFromLeafToRoot().get(0), util.getPathsFromLeafToRoot().get(1)));
		System.out.println(util.getLongestPathBetween2Leaves());
	}

}
輸出結果:
2
l21
2
l21
l11
zyf
5
5



今天我要用實力來證明我的弱小

相關推薦

暴力路徑長度

原理很簡單,二叉樹內最大的路徑的起點和終點一定是葉子。據此可以遍歷所有的葉子進行暴力求解(好好的分治法能解決的問題被我弄成這樣) 二叉樹的節點定義如下: package cn.edu.nju.zyf.longestPathWithinABinaryTree; publ

[LeetCode] Binary Tree Maximum Path Sum 路徑

Given a binary tree, find the maximum path sum. The path may start and end at any node in the tree. For example:Given the below binary tree, 1

Binary Tree Maximum Path Sum 路徑

題目描述 Given a binary tree, find the maximum path sum. The path may start and end at any node in

路徑

//二叉樹節點的定義 class TreeNode { int val; TreeNode left; TreeNode right; TreeNod

LeetCode刷題Easy篇深度

題目 Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the far

深度

package leetcode; /*Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root nod

LeetCode : 路徑

Given a binary tree, find its minimum depth.The minimum depth is the number of nodes along the short

葉子節點距離(遞迴)

題目: 輸入一顆二叉樹先序遍歷的字串,輸出該二叉樹的最大葉子節點距離 思路:先定義一個表示最大葉子節點距離的全域性變數,然後按照後續遍歷的方法訪問每一個節點, 在遍歷的過程中全域性變數隨時更新為目前出現的最大節點距離。當訪問完根節點後,全域性變數裡 的值即為最大葉節點距

C語言實現的寬度(遞迴與非遞迴版本)

一、遞迴 這裡說的遞迴,並非是指整個函式遞迴,而是說其中一個子函式使用了遞迴。整個思路可以如下:要求取最大寬度,可以迴圈求取每一層的寬度,存入一個數組,然後在這個數組裡求最大值即可,陣列下標即層數(或高度)。對於求某一層的寬度,考慮把它寫成一個子函式,引數考慮起始結點以及對

高度完整程式碼C++

我這個和之前寫的模板用的是一個,這裡求了二叉樹的高度,寬度沒寫出來, 大家就勉強看一下吧 #include <iostream> #include <string> #in

深度和小深度以及之間的差

maxheight函式就是求二叉樹的左子樹與右子樹中那個深度最大最大深度多少,minheight函式就是求二叉樹的左子樹與右子樹中那個深度最小最小深度多少,Isbalance函式就是求左子樹與右子樹的深度差,只要不大於1就是平衡二叉樹。 平衡二叉樹:它是一 棵空樹或它的左右

真題2002 2017 的帶權路徑長度

題目:二叉樹的帶權路徑長度(WPL)是二叉樹中所有葉節點的帶權路徑長度之和。給定一個二叉樹T,採用二叉連結串列儲存,節點結構為: left weight right 其中葉結點的weight域儲存該節點的非負權值。設root為指向T的根節點的指標,設計求WPL的演算法。 解答: 基本設計思想

每天一道LeetCode-----計算路徑和,路徑只需要從一個節點到達另一個節點,無其他要求

Binary Tree Maximum Path Sum 給定一個二叉樹,計算二叉樹中最長的路徑和,路徑只需要從一個節點到另一個節點,不需要經過根節點,也不需要從葉子節點開始,但至少包含一個節點 乍一看,二叉樹上任意一條路徑都有可能是最後的結果,而解

DS+圖綜合練習--路徑

ostream tree ring 一行 {} 等於 content man mil 題目描述 給定一顆二叉樹的邏輯結構(先序遍歷的結果,空樹用字符‘0’表示,例如AB0C00D00),建立該二叉樹的二叉鏈式存儲結構 二叉樹的每個結點都有一個權值,從根結點到每個葉子結點將

路徑和【124. Binary Tree Maximum Path Sum】

/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *le

的帶權路徑長度(深搜或廣搜)

下面說說這道題目。樹的帶權路徑長度(Weighted Path Length)定義:樹中所有葉子的帶權路徑長度之和。比如下面這棵樹,WPL就是3*2+7*1 = 13。 2 / \

LeetCode(124) Binary Tree Maximum Path Sum 路徑和 (如何遞迴?)

對任意一個節點,當前節點值cur, 左子樹,一條路徑值 > 0 , cur += left 右子樹,一條路徑值 > 0 , cur += right 這樣可以可以遍歷求得最大的路徑和。 ac程式碼 /** * Definition f

leetcode刷題記錄---小高度

題目描述 Given a binary tree, find its minimum depth.The minimum depth is the number of nodes along the shortest path from the root node down to the n

小深度

package leetcode; /*Given a binary tree, find its minimum depth.The minimum  depth is the number of nodes along the shortest  path from the

非遞迴/小深度

分層遍歷的思路:二叉樹分層遍歷用到的是BFS(廣度優先搜尋),顯然這必須維護一個佇列。但是一個佇列只能得到遍歷結果,並不能一層一層分開,所以必須使用兩個佇列curr和next,curr儲存當前層的所有結點指標,next儲存下一層的結點指標,遍歷的過程就是出佇列的過程,在對c