日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

左神算法:判断 t1 树中是否有与 t2 树拓扑结构完全相同的子树(Java版)

發布時間:2024/2/28 java 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 左神算法:判断 t1 树中是否有与 t2 树拓扑结构完全相同的子树(Java版) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本題來自左神《程序員代碼面試指南》“判斷 t1 樹中是否有與 t2 樹拓撲結構完全相同的子樹”題目。

題目

給定彼此獨立的兩棵樹頭節點分別為 t1 和 t2,判斷 t1 中是否有與 t2 樹拓撲結構完全相同
的子樹。
例如,如圖3-36 所示的 t1 樹和如圖 3-37 所示的 t2 樹。

題解

如果 t1 的節點數為 N,t2 的節點數為 M,則本題最優解是時間復雜度為O(N+M)的方法。

首先簡單介紹一個時間復雜度為O(N×M)的方法:

對于 t1 的每棵子樹,都去判斷是否與 t2 樹的拓撲結構完全一樣,這個過程的時間復雜度為O(M),t1 的子樹一共有 N 棵,所以時間復雜度為O(N×M),這種方法在本文中不再詳述。

下面重點介紹一下時間復雜度為O(N+M)的方法:

首先把 t1 樹和 t2 樹按照先序遍歷的方式序列化,關于這個內容,請閱讀“二叉樹的序列化和反序列化”問題。以題目的例子來說,t1 樹序列化后的結果為“1!2!4!#!8!#!#!5!9!#!#!#!3!6!#!#!7!#!#!”,記為t1Str。t2 樹序列化后的結果為“2!4!#!8!#!#!5!9!#!#!#!”,記為 t2Str。

接下來,只要驗證 t2Str 是否是 t1Str 的子串即可,這個用 KMP 算法可以在線性時間內解決

因此,t1 序列化的過程為 O(N),t2 序列化的過程為 O(M),KMP 解決 t1Str 和 t2Str 的匹配問題 O(M+N),所以時間復雜度為 O(M+N)。

有關 KMP 算法的內容,請讀者閱讀“KMP 算法”問題,關于這個算法非常清晰的解釋,這里不再詳述。

代碼

含測試用例

package chapter_3_binarytreeproblem;public class Problem_12_T1SubtreeEqualsT2 {public static class Node {public int value;public Node left;public Node right;public Node(int data) {this.value = data;}}public static boolean isSubtree(Node t1, Node t2) {String t1Str = serialByPre(t1);String t2Str = serialByPre(t2);return getIndexOf(t1Str, t2Str) != -1;}public static String serialByPre(Node head) {if (head == null) {return "#!";}String res = head.value + "!";res += serialByPre(head.left);res += serialByPre(head.right);return res;}// KMPpublic static int getIndexOf(String s, String m) {if (s == null || m == null || m.length() < 1 || s.length() < m.length()) {return -1;}char[] ss = s.toCharArray();char[] ms = m.toCharArray();int[] nextArr = getNextArray(ms);int index = 0;int mi = 0;while (index < ss.length && mi < ms.length) {if (ss[index] == ms[mi]) {index++;mi++;} else if (nextArr[mi] == -1) {index++;} else {mi = nextArr[mi];}}return mi == ms.length ? index - mi : -1;}public static int[] getNextArray(char[] ms) {if (ms.length == 1) {return new int[]{-1};}int[] nextArr = new int[ms.length];nextArr[0] = -1;nextArr[1] = 0;int pos = 2;int cn = 0;while (pos < nextArr.length) {if (ms[pos - 1] == ms[cn]) {nextArr[pos++] = ++cn;} else if (cn > 0) {cn = nextArr[cn];} else {nextArr[pos++] = 0;}}return nextArr;}public static void main(String[] args) {Node t1 = new Node(1);t1.left = new Node(2);t1.right = new Node(3);t1.left.left = new Node(4);t1.left.right = new Node(5);t1.right.left = new Node(6);t1.right.right = new Node(7);t1.left.left.right = new Node(8);t1.left.right.left = new Node(9);Node t2 = new Node(2);t2.left = new Node(4);t2.left.right = new Node(8);t2.right = new Node(5);t2.right.left = new Node(9);System.out.println(isSubtree(t1, t2));}} 超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的左神算法:判断 t1 树中是否有与 t2 树拓扑结构完全相同的子树(Java版)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。