本文为学习代码随想录 时所做的笔记,仅供学习参考,不做任何商业用途,若有侵权,请联系删除。
完全二叉树的节点个数 
222.
完全二叉树的节点个数 - 力扣(LeetCode) 
在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第
h 层,则该层包含 1~ 2^(h-1) 个节点。
 
完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。
对于情况一,可以直接用 2^树深度 - 1
来计算,注意这里根节点深度为1。
对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class  Solution  {public :     int  countNodes (TreeNode* root)   {         if  (root == nullptr ) return  0 ;         TreeNode* left = root->left;         TreeNode* right = root->right;         int  leftDepth = 0 , rightDepth = 0 ;          while  (left) {               left = left->left;             leftDepth++;         }         while  (right) {              right = right->right;             rightDepth++;         }         if  (leftDepth == rightDepth) {             return  (2  << leftDepth) - 1 ;          }         return  countNodes (root->left) + countNodes (root->right) + 1 ;     } };
 
平衡二叉树 
110.
平衡二叉树 - 力扣(LeetCode) 
二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。 
二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。 
 
递归 
明确递归函数的参数和返回值
1 2 int  getHeight (TreeNode* node) 
 
明确终止条件
1 2 3 if  (node == NULL ) {     return  0 ; }
 
明确单层递归的逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 int  leftHeight = getHeight (node->left); if  (leftHeight == -1 ) return  -1 ;int  rightHeight = getHeight (node->right); if  (rightHeight == -1 ) return  -1 ;int  result;if  (abs (leftHeight - rightHeight) > 1 ) {       result = -1 ; } else  {     result = 1  + max (leftHeight, rightHeight);  }return  result;
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class  Solution  {public :          int  getHeight (TreeNode* node)   {         if  (node == NULL ) {             return  0 ;         }         int  leftHeight = getHeight (node->left);         if  (leftHeight == -1 ) return  -1 ;         int  rightHeight = getHeight (node->right);         if  (rightHeight == -1 ) return  -1 ;         return  abs (leftHeight - rightHeight) > 1  ? -1  : 1  + max (leftHeight, rightHeight);     }     bool  isBalanced (TreeNode* root)   {         return  getHeight (root) == -1  ? false  : true ;     } };
 
二叉树的所有路径 
257.
二叉树的所有路径 - 力扣(LeetCode) 
递归 
递归函数函数参数以及返回值
1 void  traversal (TreeNode* cur, vector<int >& path, vector<string>& result) 
 
确定递归终止条件
1 2 3 if  (cur->left == NULL  && cur->right == NULL ) {      }
 
1 2 3 4 5 6 7 8 9 10 if  (cur->left == NULL  && cur->right == NULL ) {      string sPath;     for  (int  i = 0 ; i < path.size () - 1 ; i++) {          sPath += to_string (path[i]);         sPath += "->" ;     }     sPath += to_string (path[path.size () - 1 ]);      result.push_back (sPath);      return ; }
 
确定单层递归逻辑
1 2 3 4 5 6 7 8 if  (cur->left) {     traversal (cur->left, path, result);     path.pop_back ();  }if  (cur->right) {     traversal (cur->right, path, result);     path.pop_back ();  }
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class  Solution  {private :     void  traversal (TreeNode* cur, vector<int >& path, vector<string>& result)   {         path.push_back (cur->val);                   if  (cur->left == NULL  && cur->right == NULL ) {             string sPath;             for  (int  i = 0 ; i < path.size () - 1 ; i++) {                 sPath += to_string (path[i]);                 sPath += "->" ;             }             sPath += to_string (path[path.size () - 1 ]);             result.push_back (sPath);             return ;         }         if  (cur->left) {              traversal (cur->left, path, result);             path.pop_back ();          }         if  (cur->right) {              traversal (cur->right, path, result);             path.pop_back ();          }     }public :     vector<string> binaryTreePaths (TreeNode* root)   {         vector<string> result;         vector<int > path;         if  (root == NULL ) return  result;         traversal (root, path, result);         return  result;     } };
 
左叶子之和 
404.
左叶子之和 - 力扣(LeetCode) 
递归法 
确定递归函数的参数和返回值
1 int  sumOfLeftLeaves (TreeNode* root) 
 
确定终止条件
1 2 if  (root == nullptr ) 	return  0 ;
 
确定单层递归的逻辑
1 2 3 4 5 6 7 if  leftValue = sumOfLeftLeaves (root->left);if  (root->left && !root->left->left && !root->left->right) { 	leftValue = root->left->val; }int  rightValue = sumOfLeftLeaves (root->right);int  sum = leftValue + rightValue;return  sum;
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class  Solution  {public :     int  sumOfLeftLeaves (TreeNode* root)   {         if  (root == NULL ) return  0 ;         if  (root->left == NULL  && root->right== NULL ) return  0 ;         int  leftValue = sumOfLeftLeaves (root->left);             if  (root->left && !root->left->left && !root->left->right) {              leftValue = root->left->val;         }         int  rightValue = sumOfLeftLeaves (root->right);           int  sum = leftValue + rightValue;                        return  sum;     } };
 
迭代法 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class  Solution  {public :     int  sumOfLeftLeaves (TreeNode* root)   {         stack<TreeNode*> st;         if  (root == NULL ) return  0 ;         st.push (root);         int  result = 0 ;         while  (!st.empty ()) {             TreeNode* node = st.top ();             st.pop ();             if  (node->left != NULL  && node->left->left == NULL  && node->left->right == NULL ) {                 result += node->left->val;             }             if  (node->right) st.push (node->right);             if  (node->left) st.push (node->left);         }         return  result;     } };
 
找树左下角的值 
513.
找树左下角的值 - 力扣(LeetCode) 
递归 
确定递归函数的参数和返回值
1 2 3 int  maxDepth = INT_MIN;   int  result;       void  traversal (TreeNode* root, int  depth) 
 
确定终止条件
1 2 3 4 5 6 7 if  (root->left == NULL  && root->right == NULL ) {     if  (depth > maxDepth) {         maxDepth = depth;                    result = root->val;        }     return ; }
 
确定单层循环
1 2 3 4 5 6 7 8 9 10 11 12                     if  (root->left) {        depth++;      traversal (root->left, depth);     depth--;  }if  (root->right) {      depth++;      traversal (root->right, depth);     depth--;  }return ;
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class  Solution  {public :     int  maxDepth = INT_MIN;     int  result;     void  traversal (TreeNode* root, int  depth)   {         if  (root->left == NULL  && root->right == NULL ) {             if  (depth > maxDepth) {                 maxDepth = depth;                 result = root->val;             }             return ;         }         if  (root->left) {             depth++;             traversal (root->left, depth);             depth--;          }         if  (root->right) {             depth++;             traversal (root->right, depth);             depth--;          }         return ;     }     int  findBottomLeftValue (TreeNode* root)   {         traversal (root, 0 );         return  result;     } };
 
迭代法 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class  Solution  {public :     int  findBottomLeftValue (TreeNode* root)   {         queue<TreeNode*> que;         if  (root != NULL ) que.push (root);         int  result = 0 ;         while  (!que.empty ()) {             int  size = que.size ();             for  (int  i = 0 ; i < size; i++) {                 TreeNode* node = que.front ();                 que.pop ();                 if  (i == 0 ) result = node->val;                  if  (node->left) que.push (node->left);                 if  (node->right) que.push (node->right);             }         }         return  result;     } };
 
路径总和 
112. 路径总和 -
力扣(LeetCode) 
递归 
确定递归函数的参数和返回类型
1 bool  traversal (treenode* cur, int  count)    
 
确定终止条件
1 2 if  (!cur->left && !cur->right && count == 0 ) return  true ; if  (!cur->left && !cur->right) return  false ; 
 
确定单层递归的逻辑
1 2 3 4 5 6 7 8 9 10 11 if  (cur->left) {      count -= cur->left->val;      if  (traversal (cur->left, count)) return  true ;     count += cur->left->val;  }if  (cur->right) {      count -= cur->right->val;     if  (traversal (cur->right, count)) return  true ;     count += cur->right->val; }return  false ;
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class  Solution  {private :     bool  traversal (TreeNode* cur, int  count)   {         if  (!cur->left && !cur->right && count == 0 ) return  true ;          if  (!cur->left && !cur->right) return  false ;          if  (cur->left) {              count -= cur->left->val;              if  (traversal (cur->left, count)) return  true ;             count += cur->left->val;          }         if  (cur->right) {              count -= cur->right->val;              if  (traversal (cur->right, count)) return  true ;             count += cur->right->val;          }         return  false ;     }public :     bool  hasPathSum (TreeNode* root, int  sum)   {         if  (root == NULL ) return  false ;         return  traversal (root, sum - root->val);     } };
 
113. 路径总和 II
- 力扣(LeetCode) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class  solution  {private :     vector<vector<int >> result;     vector<int > path;          void  traversal (treenode* cur, int  count)   {         if  (!cur->left && !cur->right && count == 0 ) {              result.push_back (path);             return ;         }         if  (!cur->left && !cur->right) return  ;          if  (cur->left) {              path.push_back (cur->left->val);             count -= cur->left->val;             traversal (cur->left, count);                 count += cur->left->val;                     path.pop_back ();                         }         if  (cur->right) {              path.push_back (cur->right->val);             count -= cur->right->val;             traversal (cur->right, count);                count += cur->right->val;                    path.pop_back ();                         }         return  ;     }public :     vector<vector<int >> pathsum (treenode* root, int  sum) {         result.clear ();         path.clear ();         if  (root == null) return  result;         path.push_back (root->val);          traversal (root, sum - root->val);         return  result;     } };
 
从中序与后序遍历序列构造二叉树 
106.
从中序与后序遍历序列构造二叉树 - 力扣(LeetCode) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 TreeNode* traversal  (vector<int >& inorder, vector<int >& postorder)   {          if  (postorder.size () == 0 ) return  NULL ;          int  rootValue = postorder[postorder.size () - 1 ];     TreeNode* root = new  TreeNode (rootValue);          if  (postorder.size () == 1 ) return  root;          int  delimiterIndex;     for  (delimiterIndex = 0 ; delimiterIndex < inorder.size (); delimiterIndex++) {         if  (inorder[delimiterIndex] == rootValue) break ;     }                    root->left = traversal (中序左数组, 后序左数组);     root->right = traversal (中序右数组, 后序右数组);     return  root; }
 
在切割的过程中会产生四个区间,把握不好不变量的话,一会左闭右开,一会左闭右闭,必然乱套! 
中序数组相对比较好切,找到切割点(后序数组的最后一个元素)在中序数组的位置,然后切割,如下代码中我坚持左闭右开的原则:
1 2 3 4 5 6 7 8 9 10 int  delimiterIndex;for  (delimiterIndex = 0 ; delimiterIndex < inorder.size (); delimiterIndex++) {     if  (inorder[delimiterIndex] == rootValue) break ; }vector<int > leftInorder (inorder.begin(), inorder.begin() + delimiterIndex)  ;vector<int > rightInorder (inorder.begin() + delimiterIndex + 1 , inorder.end() )  ;
 
接下来就要切割后序数组了。
首先后序数组的最后一个元素指定不能要了,这是切割点 也是
当前二叉树中间节点的元素,已经用了。
后序数组的切割点怎么找?
后序数组没有明确的切割元素来进行左右切割,不像中序数组有明确的切割点,切割点左右分开就可以了。
此时有一个很重的点,就是中序数组大小一定是和后序数组的大小相同的(这是必然)。 
中序数组我们都切成了左中序数组和右中序数组了,那么后序数组就可以按照左中序数组的大小来切割,切成左后序数组和右后序数组。
1 2 3 4 5 6 7  postorder.resize (postorder.size () - 1 );vector<int > leftPostorder (postorder.begin(), postorder.begin() + leftInorder.size())  ;vector<int > rightPostorder (postorder.begin() + leftInorder.size(), postorder.end())  ;
 
此时,中序数组切成了左中序数组和右中序数组,后序数组切割成左后序数组和右后序数组。
接下来可以递归了,代码如下:
1 2 root->left = traversal (leftInorder, leftPostorder); root->right = traversal (rightInorder, rightPostorder);
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class  Solution  {private :     TreeNode* traversal  (vector<int >& inorder, vector<int >& postorder)   {         if  (postorder.size () == 0 ) return  NULL ;                  int  rootValue = postorder[postorder.size () - 1 ];         TreeNode* root = new  TreeNode (rootValue);                  if  (postorder.size () == 1 ) return  root;                  int  delimiterIndex;         for  (delimiterIndex = 0 ; delimiterIndex < inorder.size (); delimiterIndex++) {             if  (inorder[delimiterIndex] == rootValue) break ;         }                           vector<int > leftInorder (inorder.begin(), inorder.begin() + delimiterIndex)  ;                  vector<int > rightInorder (inorder.begin() + delimiterIndex + 1 , inorder.end() )  ;                  postorder.resize (postorder.size () - 1 );                                    vector<int > leftPostorder (postorder.begin(), postorder.begin() + leftInorder.size())  ;                  vector<int > rightPostorder (postorder.begin() + leftInorder.size(), postorder.end())  ;         root->left = traversal (leftInorder, leftPostorder);         root->right = traversal (rightInorder, rightPostorder);         return  root;     }public :     TreeNode* buildTree (vector<int >& inorder, vector<int >& postorder)   {         if  (inorder.size () == 0  || postorder.size () == 0 ) return  NULL ;         return  traversal (inorder, postorder);     } };
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class  Solution  {private :          TreeNode* traversal  (vector<int >& inorder, int  inorderBegin, int  inorderEnd, vector<int >& postorder, int  postorderBegin, int  postorderEnd)   {         if  (postorderBegin == postorderEnd) return  NULL ;         int  rootValue = postorder[postorderEnd - 1 ];         TreeNode* root = new  TreeNode (rootValue);         if  (postorderEnd - postorderBegin == 1 ) return  root;         int  delimiterIndex;         for  (delimiterIndex = inorderBegin; delimiterIndex < inorderEnd; delimiterIndex++) {             if  (inorder[delimiterIndex] == rootValue) break ;         }                           int  leftInorderBegin = inorderBegin;         int  leftInorderEnd = delimiterIndex;                  int  rightInorderBegin = delimiterIndex + 1 ;         int  rightInorderEnd = inorderEnd;                           int  leftPostorderBegin =  postorderBegin;         int  leftPostorderEnd = postorderBegin + delimiterIndex - inorderBegin;                   int  rightPostorderBegin = postorderBegin + (delimiterIndex - inorderBegin);         int  rightPostorderEnd = postorderEnd - 1 ;          root->left = traversal (inorder, leftInorderBegin, leftInorderEnd,  postorder, leftPostorderBegin, leftPostorderEnd);         root->right = traversal (inorder, rightInorderBegin, rightInorderEnd, postorder, rightPostorderBegin, rightPostorderEnd);         return  root;     }public :     TreeNode* buildTree (vector<int >& inorder, vector<int >& postorder)   {         if  (inorder.size () == 0  || postorder.size () == 0 ) return  NULL ;                  return  traversal (inorder, 0 , inorder.size (), postorder, 0 , postorder.size ());     } };
 
从前序与中序遍历序列构造二叉树 
105.
从前序与中序遍历序列构造二叉树 - 力扣(LeetCode) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 class  Solution  {private :         TreeNode* traversal  (vector<int >& inorder, int  inorderBegin, int  inorderEnd, vector<int >& preorder, int  preorderBegin, int  preorderEnd)   {         if  (preorderBegin == preorderEnd) return  NULL ;         int  rootValue = preorder[preorderBegin];          TreeNode* root = new  TreeNode (rootValue);         if  (preorderEnd - preorderBegin == 1 ) return  root;         int  delimiterIndex;         for  (delimiterIndex = inorderBegin; delimiterIndex < inorderEnd; delimiterIndex++) {             if  (inorder[delimiterIndex] == rootValue) break ;         }                           int  leftInorderBegin = inorderBegin;         int  leftInorderEnd = delimiterIndex;                  int  rightInorderBegin = delimiterIndex + 1 ;         int  rightInorderEnd = inorderEnd;                           int  leftPreorderBegin =  preorderBegin + 1 ;         int  leftPreorderEnd = preorderBegin + 1  + delimiterIndex - inorderBegin;                   int  rightPreorderBegin = preorderBegin + 1  + (delimiterIndex - inorderBegin);         int  rightPreorderEnd = preorderEnd;         root->left = traversal (inorder, leftInorderBegin, leftInorderEnd,  preorder, leftPreorderBegin, leftPreorderEnd);         root->right = traversal (inorder, rightInorderBegin, rightInorderEnd, preorder, rightPreorderBegin, rightPreorderEnd);         return  root;     }public :     TreeNode* buildTree (vector<int >& preorder, vector<int >& inorder)   {         if  (inorder.size () == 0  || preorder.size () == 0 ) return  NULL ;                  return  traversal (inorder, 0 , inorder.size (), preorder, 0 , preorder.size ());     } };
 
最大二叉树 
654.
最大二叉树 - 力扣(LeetCode) 
确定递归函数的参数和返回值
1 TreeNode* constructMaximumBinaryTree (vector<int >& nums)  
 
确定终止条件
1 2 3 4 5 TreeNode* node = new  TreeNode (0 );if  (nums.size () == 1 ) {     node->val = nums[0 ];     return  node; }
 
确定单层递归的逻辑
先要找到数组中最大的值和对应的下标,
最大的值构造根节点,下标用来下一步分割数组。
1 2 3 4 5 6 7 8 9 10 int  maxValue = 0 ;int  maxValueIndex = 0 ;for  (int  i = 0 ; i < nums.size (); i++) {     if  (nums[i] > maxValue) {         maxValue = nums[i];         maxValueIndex = i;     } } TreeNode* node = new  TreeNode (0 ); node->val = maxValue;
 
最大值所在的下标左区间 构造左子树
1 2 3 4 if  (maxValueIndex > 0 ) {     vector<int > newVec (nums.begin(), nums.begin() + maxValueIndex)  ;     node->left = constructMaximumBinaryTree (newVec); }
 
最大值所在的下标右区间构造右子树
1 2 3 4 if  (maxValueIndex < (nums.size () - 1 )) {     vector<int > newVec (nums.begin() + maxValueIndex + 1 , nums.end())  ;     node->right = constructMaximumBinaryTree (newVec); }
 
  
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class  Solution  {public :     TreeNode* constructMaximumBinaryTree (vector<int >& nums)   {         TreeNode* node = new  TreeNode (0 );         if  (nums.size () == 1 ) {             node->val = nums[0 ];             return  node;         }                  int  maxValue = 0 ;         int  maxValueIndex = 0 ;         for  (int  i = 0 ; i < nums.size (); i++) {             if  (nums[i] > maxValue) {                 maxValue = nums[i];                 maxValueIndex = i;             }         }         node->val = maxValue;                  if  (maxValueIndex > 0 ) {             vector<int > newVec (nums.begin(), nums.begin() + maxValueIndex)  ;             node->left = constructMaximumBinaryTree (newVec);         }                  if  (maxValueIndex < (nums.size () - 1 )) {             vector<int > newVec (nums.begin() + maxValueIndex + 1 , nums.end())  ;             node->right = constructMaximumBinaryTree (newVec);         }         return  node;     } };