1 Same Tree
https://leetcode.com/problems/same-tree/
Given two binary trees, write a function to check if they are equal or not.
Two binary trees are considered equal if they are structurally identical and the nodes have the same value.
分治的思想,如果root相等,再看左右子树是否相等。
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: bool isSameTree(TreeNode* p, TreeNode* q) { if (p == NULL && q == NULL) { return true; } if (p == NULL || q == NULL) { return false; } if (p->val != q->val) { return false; } return isSameTree(p->left, q->left) && isSameTree(p->right, q->right); } };
2 SubTree
http://www.lintcode.com/en/problem/subtree/
You have two every large binary trees:
T1
, with millions of nodes, andT2
, with hundreds of nodes. Create an algorithm to decide ifT2
is a subtree ofT1
.Example
T2 is a subtree of T1 in the following case:
1 3 / \ / T1 = 2 3 T2 = 4 / 4
T2 isn‘t a subtree of T1 in the following case:
1 3 / \ T1 = 2 3 T2 = 4 / 4
仍然是分治的思想。如果T1当前root节点与T2的root节点相同,我们才有兴趣判断T2是否是T1的子树。如果不同,判断T2是否是T1的左子树的子树或者是T1的右子树的子树。
/** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left, *right; * TreeNode(int val) { * this->val = val; * this->left = this->right = NULL; * } * } */ class Solution { public: /** * @param T1, T2: The roots of binary tree. * @return: True if T2 is a subtree of T1, or false. */ bool isSubtree(TreeNode *T1, TreeNode *T2) { if (T2 == NULL) { return true; } // //we have exhauste the root1 already if (T1 == NULL) { return false; } if (T1->val == T2->val) { if (isSameTree(T1, T2)) { return true; } } return isSubtree(T1->left, T2) || isSubtree(T1->right, T2); } private: bool isSameTree(TreeNode *T1, TreeNode *T2) { if (T1 == NULL && T2 == NULL) { return true; } if (T1 == NULL || T2 == NULL) { return false; } if (T1->val != T2->val) { return false; } return isSameTree(T1->left, T2->left) && isSameTree(T1->right, T2->right); } };
3 计算树的深度
int treeDepth(TreeNode *root) { // base case if (root == NULL) { return 0; } return max(treeDepth(root->left), treeDepth(root->right)) + 1; }
4 Path Sum
https://leetcode.com/problems/path-sum/
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.
For example:
Given the below binary tree and
sum = 22
,5 / 4 8 / / 11 13 4 / \ 7 2 1return true, as there exist a root-to-leaf path
5->4->11->2
which sum is 22.
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: bool hasPathSum(TreeNode* root, int sum) { // base case if (root == NULL) { return false; } // 当前递归层是否满足条件? if (root->val == sum && root->left == NULL && root->right == NULL) { return true; } return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val); } };
5 Path Sum II
https://leetcode.com/problems/path-sum-ii/
Given a binary tree and a sum, find all root-to-leaf paths where each path‘s sum equals the given sum.
For example:
Given the below binary tree and
sum = 22
,5 / 4 8 / / 11 13 4 / \ / 7 2 5 1return
[ [5,4,11,2], [5,8,4,5] ]
解法1:
dfs中的sum参数记录了当前递归层需要满足的条件
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<vector<int>> pathSum(TreeNode* root, int sum) { vector<vector<int>> result; vector<int> path; dfs(root, result, path, sum); return result; } private: void dfs(TreeNode *root, vector<vector<int>> &result, vector<int> &path, int sum) { if (root == NULL) { return; } path.push_back(root->val); if (root->val == sum && root->left == NULL && root->right == NULL) { result.push_back(path); } dfs(root->left, result, path, sum - root->val); dfs(root->right, result, path, sum - root->val); path.pop_back(); } };
解法2:
考虑几个问题,dfs的对象是谁?什么时候满足push到result的条件?递归基是什么?
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<vector<int>> pathSum(TreeNode* root, int sum) { vector<vector<int>> result; vector<int> path; dfs(root, result, path, sum); return result; } private: void dfs(TreeNode *root, vector<vector<int>> &result, vector<int> &path, const int &sum) { if (root == NULL) { return; } path.push_back(root->val); if (root->left == NULL && root->right == NULL) { int tmp = 0; for (vector<int>::const_iterator itr = path.cbegin(); itr != path.cend(); itr++) { tmp += *itr; } if (tmp == sum) { result.push_back(path); } } dfs(root->left, result, path, sum); dfs(root->right, result, path, sum); path.pop_back(); } };
6 Binary Tree Maximum Path Sum
https://leetcode.com/problems/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 / 2 3Return
6
.
采用分治法。要求当前tree的最大路径和,可以考虑左子树的最大路径和、右子树的最大路径和、以及包含当前结点的最大路径和三者中的最大值。
要求包含当前结点的最大路径和,需要知道左子树的单路最大路径和leftChildSingleMaxSum、右子树的单路最大路径和rightChildSingleMaxSum。其中,max( leftChildSingleMaxSum + rightChildSingleMaxSum + root->val, leftChildSingleMaxSum + root->val, rightChildSingleMaxSum + root->val),即为包含当前结点的最大路径和。
由以上分析,不难得知,遍历每一个节点时,需要得到其单路最大路径和以及双路最大路径和。我们将其封装为returnType。
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ struct returnType { returnType(int singlePath, int doublePath) :singlePath_(singlePath), doublePath_(doublePath) { } int singlePath_; int doublePath_; }; class Solution { public: int maxPathSum(TreeNode* root) { return maxPathSumHelper(root).doublePath_; } private: returnType maxPathSumHelper(TreeNode *root) { if (root == NULL) { return returnType(0, numeric_limits<int>::min()); } // devide returnType left = maxPathSumHelper(root->left); returnType right = maxPathSumHelper(root->right); // conquer int singlePath = getMax(left.singlePath_ + root->val, right.singlePath_ + root->val, root->val); int doublePath = getMax(left.doublePath_, right.doublePath_, max(left.singlePath_ + right.singlePath_ + root->val, singlePath)); return returnType(singlePath, doublePath); } int getMax(int x, int y, int z) { return (x = x > y ? x : y ) > z ? x : z; } };
7 最近公共祖先
http://www.lintcode.com/zh-cn/problem/lowest-common-ancestor/
最近公共祖先
给定一棵二叉树,找到两个节点的最近公共父节点(LCA)。
最近公共祖先是两个节点的公共的祖先节点且具有最大深度。
样例
对于下面这棵二叉树
4 / 3 7 / 5 6
LCA(3, 5) =
4
LCA(5, 6) =
7
LCA(6, 7) =
7
如果两个节点都在同一棵子树中,则继续往该子树中查找。如果两个节点在不同的子树中,那么root即为最近公共祖先。
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q) { // p,q均在左子树中 if (covers(root->left, p) && covers(root->left, q)) { return lowestCommonAncestor(root->left, q, p); } // p,q均在右子树中 if (covers(root->right, p) && covers(root->right, q)) { return lowestCommonAncestor(root->right, q, p); } // base case:p,q在不同的子树中,或者root即为p,q中的某一个节点 return root; } // 辅助函数,判断节点p是否在子树中。 bool covers(TreeNode *root, TreeNode *p) { if (root == NULL) { return false; } if (root == p) { return true; } return covers(root->left, p) || covers(root->right, p); } };
8 Convert Sorted Array to Binary Search Tree
Tree与其他数据结构转换这类题?目要求将树的结构转化成其他数据结构,例如linked list, array等,或者反之,从array等结构构成?棵树。
前者通常是通过树的遍历,合并局部解来得到全局解,而后者则可以利?分治的策略,递归将数据结构的两部分分别转换成子树,再合并。
https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/
Given an array where elements are sorted in ascending order, convert it to a height balanced BST.
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode* sortedArrayToBST(vector<int>& nums) { return sortedArrayToBstHelper(nums, 0, nums.size() - 1); } private: TreeNode* sortedArrayToBstHelper(const vector<int> &nums, int start, int end) { if (start > end) { return NULL; } if (start == end) { return new TreeNode(nums[start]); } int mid = start + ((end - start) >> 1); TreeNode *l = sortedArrayToBstHelper(nums, start, mid - 1); TreeNode *r = sortedArrayToBstHelper(nums, mid + 1, end); TreeNode *root = new TreeNode(nums[mid]); root->left = l; root->right = r; return root; } };
9