這是悅樂書的第374次更新,第401篇原創
java
今天介紹的是LeetCode
算法題中Easy
級別的第235
題(順位題號是993
)。在二叉樹中,根節點在深度0處,而且每一個深度爲k
的節點的子節點,他們深度爲k + 1
。node
若是二元樹的兩個節點具備相同的深度但具備不一樣的父節點,則它們是堂兄弟。算法
咱們給出了具備惟一值的二叉樹root
,以及樹中兩個不一樣節點的值x
和y
。數組
當且僅當對應於值x和y的節點是堂兄弟時,才返回true
。例如:數據結構
輸入:root = [1,2,3,4],x = 4,y = 3code
1 / \ 2 3 / 4
輸出:false
輸入:root = [1,2,3,null,4,null,5],x = 5,y = 4遞歸
1 / \ 2 3 \ \ 4 5
輸出:true
輸入:root = [1,2,3,null,4],x = 2,y = 3隊列
1 / \ 2 3 \ 4
輸出:falseget
注意:it
樹中的節點數將介於2和100之間。
每一個節點都有一個從1到100的惟一整數值。
題目的意思是x
和y
在同一層,可是他們的父級節點不同,也就是x
和y
屬於堂兄弟的關係。
使用BFS(廣度優先)的算法,經過迭代的方式藉助Stack
來實現,使用了一個額外的方法,分別求出x
和y
的層級和他們的父級節點,用一個長度爲2的數組返回,若是x
和y
的層級相同且父級結點不一樣,就返回true
。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public boolean isCousins(TreeNode root, int x, int y) { int[] arr = getTreeDepth(root, x); int[] arr2 = getTreeDepth(root, y); if (arr.length < 1 || arr2.length < 1) { return false; } return arr[0] != arr2[0] && arr[1] == arr2[1]; } public int[] getTreeDepth(TreeNode root, int num) { Stack<TreeNode> stack = new Stack<TreeNode>(); stack.push(root); int depth = 0; while (!stack.isEmpty()) { Stack<TreeNode> stack2 = new Stack<TreeNode>(); while (!stack.isEmpty()) { TreeNode tem = stack.pop(); if (tem.left != null) { // 當前節點的左子節點值等於要找的數 if (tem.left.val == num) { return new int[] {tem.val, depth+1}; } stack2.push(tem.left); } if (tem.right != null) { // 當前節點的右子節點值等於要找的數 if (tem.right.val == num) { return new int[] {tem.val, depth+1}; } stack2.push(tem.right); } } stack = stack2; depth++; } return new int[] {}; }
針對第一種解法,咱們也能夠將判斷的方法融合在一塊兒,依舊是藉助棧。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public boolean isCousins2(TreeNode root, int x, int y) { Stack<TreeNode> stack = new Stack<TreeNode>(); stack.push(root); while (!stack.isEmpty()) { Stack<TreeNode> stack2 = new Stack<TreeNode>(); boolean xExist = false, yExist = false; while (!stack.isEmpty()) { TreeNode tem = stack.pop(); if (tem.val == x) { xExist = true; } if (tem.val == y) { yExist = true; } // x和y不能有同一個父節點 if (tem.left != null && tem.right != null) { if (tem.left.val == x && tem.right.val == y) { return false; } if (tem.left.val == y && tem.right.val == x) { return false; } } if (tem.left != null) { stack2.push(tem.left); } if (tem.right != null) { stack2.push(tem.right); } } stack = stack2; if (xExist && yExist) { return true; } } return false; }
和第二種解法思路同樣,只是將棧換成了隊列。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public boolean isCousins3(TreeNode root, int x, int y) { Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { int size = queue.size(); boolean xExist = false, yExist = false; for (int i=0; i<size; i++) { TreeNode tem = queue.poll(); if (tem.val == x) { xExist = true; } if (tem.val == y) { yExist = true; } // x和y不能有同一個父節點 if (tem.left != null && tem.right != null) { if (tem.left.val == x && tem.right.val == y) { return false; } if (tem.left.val == y && tem.right.val == x) { return false; } } if (tem.left != null) { queue.offer(tem.left); } if (tem.right != null) { queue.offer(tem.right); } } if (xExist && yExist) { return true; } } return false; }
藉助遞歸,一個遞歸方法求深度,一個遞歸方法找父節點,最後判斷深度是否相同且父節點不一樣。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public boolean isCousins4(TreeNode root, int x, int y) { return getDepth(root, x, 0) == getDepth(root, y, 0) && findParent(root, x) != findParent(root, y); } public int getDepth(TreeNode root, int num, int depth){ if (root == null) { return 0; } if (root.val == num) { return depth; } int left = getDepth(root.left, num, depth+1); int right = getDepth(root.right, num, depth+1); return Math.max(left, right); } public int findParent(TreeNode root, int num) { if (root == null) { return 0; } if (root.left != null && root.left.val == num) { return root.val; } if (root.right != null && root.right.val == num) { return root.val; } int left = findParent(root.left, num); int right = findParent(root.right, num); return Math.max(left, right); }
咱們也能夠只是用一次遞歸方法,藉助全局變量來解。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ private int depthX; private int depthY; private TreeNode parentX; private TreeNode parentY; public boolean isCousins5(TreeNode root, int x, int y) { helper(root, x, y, 0, null); return depthX == depthY && parentX != parentY; } public void helper(TreeNode root, int x, int y, int depth, TreeNode parent) { if (root == null) { return ; } if (root.val == x) { depthX = depth; parentX = parent; } else if (root.val == y) { depthY = depth; parentY = parent; } helper(root.left, x, y, depth+1, root); helper(root.right, x, y, depth+1, root); }
咱們還能夠將第五種解法中找父節點的變量換成int
類型,由於節點值惟一,能夠直接使用節點值參與判斷。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ private int depthX; private int depthY; private int parentX; private int parentY; public boolean isCousins6(TreeNode root, int x, int y) { helper(root, x, y, 0, 0); return depthX == depthY && parentX != parentY; } public void helper(TreeNode root, int x, int y, int depth, int parent) { if (root == null) { return ; } if (root.val == x) { depthX = depth; parentX = parent; } else if (root.val == y) { depthY = depth; parentY = parent; } helper(root.left, x, y, depth+1, root.val); helper(root.right, x, y, depth+1, root.val); }
算法專題目前已連續日更超過七個月,算法題文章241+篇,公衆號對話框回覆【數據結構與算法】、【算法】、【數據結構】中的任一關鍵詞,獲取系列文章合集。
以上就是所有內容,若是你們有什麼好的解法思路、建議或者其餘問題,能夠下方留言交流,點贊、留言、轉發就是對我最大的回報和支持!