一刷leetcode——树

94. Binary Tree Inorder Traversal

题意:中序遍历二叉树

我的思路:递归水题

我的代码:

/**
 * 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:
    void dfs(TreeNode* root, vector<int> &ans) {
        if (root->left) dfs(root->left, ans);
        ans.push_back(root->val);
        if (root->right) dfs(root->right, ans);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ans;
        if (root) dfs(root, ans);
        return ans;
    }
};
View Code

九章最优解:一样

class Solution {
    /**
     * @param root: The root of binary tree.
     * @return: Inorder in vector which contains node values.
     */
public:
    vector<int> inorder;

    void traverse(TreeNode *root) {
        if (root == NULL) {
            return;
        }
        traverse(root->left);
        inorder.push_back(root->val);
        traverse(root->right);
    }

    vector<int> inorderTraversal(TreeNode *root) {
        inorder.clear();
        traverse(root);
        return inorder;
        // write your code here
    }
};
View Code

95. Unique Binary Search Trees II

题意:输出1~n构成的所有二叉树

我的思路:dfs

我的代码:

class Solution {
public:
    vector<TreeNode*> dfs(int f, int t) {
        vector<TreeNode*> ret;
        if (f == t) {
            TreeNode* tmp = new TreeNode(f);
            ret.push_back(tmp);
        } else if (f < t) {
            for (int i = f; i <= t; i++) {
                vector<TreeNode*> l = dfs(f, i-1), r = dfs(i+1, t);
                for (int j = 0; j < l.size(); j++)
                    for (int k = 0; k < r.size(); k++) {
                        TreeNode* tmp = new TreeNode(i);
                        tmp->left = l[j];
                        tmp->right = r[k];
                        ret.push_back(tmp);
                    }
            }
        } else {
            ret.push_back(NULL);
        }
        return ret;
    }
    vector<TreeNode*> generateTrees(int n) {
        if (n == 0) {
            vector<TreeNode*> ret;
            return ret;
        }
        return dfs(1, n);
    }
};
View Code

98. Validate Binary Search Tree

题意:检验是否是正确的二叉搜索树

我的思路:dfs中序遍历

我的代码:

class Solution {
public:
    TreeNode* pre;
    void dfs(TreeNode* root, int &ans) {
        if (root->left) dfs(root->left, ans);
        if (pre && root->val <= pre->val) {
            ans = 0;
            return;
        }
        pre = root;
        if (root->right) dfs(root->right, ans);
    }
    bool isValidBST(TreeNode* root) {
        int ans = 1;
        if (root) dfs(root, ans);
        return ans;
    }
};
View Code

99. Recover Binary Search Tree

题意:给定二叉搜索树中有两个节点错位,将他们复位

我的思路:二叉搜索树中序遍历应当是递增序列,根据这一性质即可找出错位的节点

我的代码:

class Solution {
public:
    TreeNode* pre, *p1, *p2;
    void dfs(TreeNode* root) {       //中序遍历
        if (root->left) dfs(root->left);
        if (pre && pre->val > root->val) {
            if (p1 == NULL) {
                p1 = pre;
                p2 = root;
            } else
                p2 = root;
        }
        pre = root;
        if (root->right) dfs(root->right);
    }
    void recoverTree(TreeNode* root) {
        if (root) {
            dfs(root);
            swap(p1->val, p2->val);
        }
        return;
    }
};
View Code

101. Symmetric Tree

题意:判断一棵二叉树是否镜像

我的思路:递归解法,bugfree

我的代码:

/**
 * 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 dfs(TreeNode* l, TreeNode* r) {
        if (l->val != r->val) return 0;
        if (l->left == NULL && l->right == NULL && r->left == NULL && r->right == NULL) return 1;
        if (l->left == NULL && r->right == NULL && r->left != NULL && l->right != NULL) return dfs(l->right, r->left);
        if (r->left == NULL && l->right == NULL && l->left != NULL && r->right != NULL) return dfs(l->left, r->right);
        if (r->left != NULL && l->right != NULL && l->left != NULL && r->right != NULL) return dfs(l->left, r->right) && dfs(l->right, r->left);
        return 0;
    }
    bool isSymmetric(TreeNode* root) {
        if (root == NULL) return 1;
        if (root->left == NULL && root->right == NULL) return 1;
        if (root->left == NULL || root->right == NULL) return 0;
        return dfs(root->left, root->right);
    }
};
View Code

102. Binary Tree Level Order Traversal

题意:将树分层形成一个vector<vector<int>>,每层从左到右

我的思路:记录层dfs,bugfree

我的代码:

/**
 * 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:
    void dfs(TreeNode* root, vector<vector<int>> &ans, int i) {
        if (root == NULL) return;
        if (ans.size() <= i) {
            vector<int> tmp;
            ans.push_back(tmp);
        }
        ans[i].push_back(root->val);
        if (root->left) dfs(root->left, ans, i+1);
        if (root->right) dfs(root->right, ans, i+1);
    }
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> ans;
        dfs(root, ans, 0);
        return ans;
    }
};
View Code

九章最优解:BFS

public:
    vector<vector<int>> levelOrder(TreeNode *root) {
        vector<vector<int>> result;
        if (root == NULL) {
            return result;
        }
        
        queue<TreeNode *> Q;
        Q.push(root);
        while (!Q.empty()) {
            int size = Q.size();
            vector<int> level;
            
            for (int i = 0; i < size; i++) {
                TreeNode *head = Q.front(); Q.pop();
                level.push_back(head->val);
                if (head->left != NULL) {
                    Q.push(head->left);
                }
                if (head->right != NULL) {
                    Q.push(head->right);
                }
            }
            
            result.push_back(level);
        }
        
        return result;
    }
};
View Code

107. Binary Tree Level Order Traversal II

题意:将树分层输出,下层先出

我的思路:把上题的结果倒置输出

我的代码:

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        vector<vector<int>> result;
        if (root == NULL) {
            return result;
        }
        queue<TreeNode *> Q;
        Q.push(root);
        while (!Q.empty()) {
            int size = Q.size();
            vector<int> level;
            for (int i = 0; i < size; i++) {
                TreeNode *head = Q.front(); Q.pop();
                level.push_back(head->val);
                if (head->left != NULL) {
                    Q.push(head->left);
                }
                if (head->right != NULL) {
                    Q.push(head->right);
                }
            }
            result.push_back(level);
        }
        reverse(result.begin(), result.end());
        return result;
    }
};
View Code

九章最优解:一样

103. Binary Tree Zigzag Level Order Traversal

题意:将一棵二叉树从上到下之字形输出

我的思路:bfs+栈,两个栈轮着用,一层从左往右进,一层从右往左进

我的代码:

/**
 * 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>> zigzagLevelOrder(TreeNode* root) {
        vector<vector<int>> result;
        if (root == NULL) return result;
        stack<TreeNode *> s[2];
        bool flag = 1;
        s[flag].push(root);
        while (!s[flag].empty()) {
            vector<int> tmp;
            int t = flag^1, n = s[flag].size();
            for (int i = 0; i < n; i++) {
                TreeNode *head = s[flag].top();
                s[flag].pop();
                tmp.push_back(head->val);
                if (flag) {
                    if (head->left != NULL) s[t].push(head->left);
                    if (head->right != NULL) s[t].push(head->right);
                } else  {
                    if (head->right != NULL) s[t].push(head->right);
                    if (head->left != NULL) s[t].push(head->left);
                }
            }
            result.push_back(tmp);
            flag = flag^1;
        }
        return result;
    }
};
View Code

九章最优解:开一个结构体node记录层数,该翻转翻转

struct Node
{
    TreeNode *node;
    int level;
    Node(){}
    Node(TreeNode *n, int l):node(n), level(l){}
}; 
class Solution {
    /**
     * @param root: The root of binary tree.
     * @return: A list of lists of integer include 
     *          the zigzag level order traversal of its nodes' values 
     */
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode *root) {
        // write your code here
        vector<vector<int> > ret;
        ret.clear();       
        if (root == NULL)
            return ret;        
        queue<Node> q;        
        q.push(Node(root, 0));        
        int curLevel = -1;        
        vector<int> a;        
        while(!q.empty())
        {
            Node node = q.front();            
            if (node.node->left)
                q.push(Node(node.node->left, node.level + 1));           
            if (node.node->right)
                q.push(Node(node.node->right, node.level + 1));   
            if (curLevel != node.level)
            {
                if (curLevel != -1)
                {
                    if (curLevel % 2 == 1)
                        reverse(a.begin(), a.end());
                        
                    ret.push_back(a);
                }
                a.clear();
                curLevel = node.level;
            }
            a.push_back(node.node->val);
            q.pop();
        }        
        if (curLevel % 2 == 1)
            reverse(a.begin(), a.end());   
        ret.push_back(a);
        return ret;
    }
};
View Code

109. Convert Sorted List to Binary Search Tree

题意:将一个有序链表变成二叉搜索树

我的思路:dfs,类似108,找中间节点作为根,递归左右

我的代码:

class Solution {
public:
    TreeNode* dfs(ListNode* head, int f, int t) {
        int mid = (f+t)/2, cnt = 0;
        ListNode* tmp = head;
        while (cnt < mid) {
            tmp = tmp->next;
            cnt++;
        }
        TreeNode* ret = new TreeNode(tmp->val);
        if (mid > f) ret->left = dfs(head, f, mid-1);
        if (mid < t) ret->right = dfs(head, mid+1, t);
        return ret;
    }
    TreeNode* sortedListToBST(ListNode* head) {
        int size = 0;
        ListNode* tmp = head;
        while (tmp) {
            size++;
            tmp = tmp->next;
        }
        if (size == 0) return NULL;
        return dfs(head, 0, size-1);
    }
};
View Code

110. Balanced Binary Tree

题意:判Balanced Binary Tree,即每个节点的高度差不大于1

我的思路:常规dfs

我的代码:

class Solution {
public:
    int maxdepth(TreeNode* root, int &ans) {
        if (root == NULL) return 0;
        int l = maxdepth(root->left, ans), r = maxdepth(root->right, ans);
        if (abs(l-r) > 1) ans = 0;
        return max(l, r)+1;
    }
    bool isBalanced(TreeNode* root) {
        int ans = 1;
        maxdepth(root, ans);
        return ans;
    }
};
View Code

114. Flatten Binary Tree to Linked List

题意:将一个二叉树的前序遍历拉成只有右子树的链表状

我的思路:对于每个节点,将他的左子树放到右子树上,原来的右子树连到左子树最右下角

我的代码:

class Solution {
public:
    void flatten(TreeNode* root) {
        while (root) {
            if (root->left) {
                TreeNode* tmp = root->left;
                while (tmp->right) tmp = tmp->right;
                tmp->right = root->right;
                root->right = root->left;
                root->left = NULL;
            }
            root = root->right;
        }
    }
};
View Code

116. Populating Next Right Pointers in Each Node

题意:树结构体中增加一个next指针,将它指向同一层右边的节点,最右边那个指向空

我的思路:队列

我的代码:

class Solution {
public:
    void connect(TreeLinkNode *root) {
        if (root == NULL) return;
        queue<TreeLinkNode *> q;
        q.push(root);
        while (!q.empty()) {
            TreeLinkNode *r = NULL;
            int n = q.size();
            for (int i = 0; i < n; i++) {
                TreeLinkNode *tmp = q.front();
                q.pop();
                if (tmp->right) q.push(tmp->right);
                if (tmp->left) q.push(tmp->left);
                tmp->next = r;
                r = tmp;
            }
        }
    }
};
View Code

117. Populating Next Right Pointers in Each Node II

题意:上题是满树,这次每层节点可能不满

我的思路:跟上题一个代码,不用考虑

124. Binary Tree Maximum Path Sum

题意:输出二叉树的最大路径和

我的思路:dfs

我的代码:

class Solution {
public:
    int ans = 0x80000000;
    int dfs(TreeNode* root) {
        if (root == NULL) return 0;
        int l = dfs(root->left),  r = dfs(root->right);
        ans = max(ans, root->val+max(l, 0)+max(r, 0));
        return root->val+max(max(l, r), 0);
    }
    int maxPathSum(TreeNode* root) {
        dfs(root);
        return ans;
    }
};
View Code

144. Binary Tree Preorder Traversal 

题意:二叉树前序遍历

我的思路:递归水题

我的代码:

/**
 * 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:
    void dfs(TreeNode* root, vector<int> &ans) {
        ans.push_back(root->val);
        if (root->left) dfs(root->left, ans);
        if (root->right) dfs(root->right, ans);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        if (root) dfs(root, ans);
        return ans;
    }
};
View Code

九章最优解:一样

class Solution {
public:
    vector<int> preorder;

    void traverse(TreeNode *root) {
        if (root == NULL) {
            return;
        }
        preorder.push_back(root->val);
        traverse(root->left);
        traverse(root->right);
    }

    vector<int> preorderTraversal(TreeNode *root) {
        preorder.clear();
        traverse(root);
        return preorder;
    }
};
View Code

145. Binary Tree Postorder Traversal

题意:二叉树后序遍历

我的思路:递归水题

我的代码:

class Solution {
public:
    void dfs(TreeNode* root, vector<int> &ans) {
        if (root->left) dfs(root->left, ans);
        if (root->right) dfs(root->right, ans);
        ans.push_back(root->val);
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ans;
        if (root == NULL) return ans;
        dfs(root, ans);
        return ans;
    }
};
View Code

九章最优解:用栈不用递归

class Solution {
public:
    vector<int> postorderTraversal(TreeNode *root) {
        vector<int> result;
        stack<TreeNode *> myStack;
        
        TreeNode *current = root, *lastVisited = NULL;
        while (current != NULL || !myStack.empty()) {
            while (current != NULL) {
                myStack.push(current);
                current = current->left;
            }
            current = myStack.top(); 
            if (current->right == NULL || current->right == lastVisited) {
                myStack.pop();
                result.push_back(current->val);
                lastVisited = current;
                current = NULL;
            } else {
                current = current->right;
            }
        }
        return result;
    }
};
View Code

104. Maximum Depth of Binary Tree

题意:输出给定二叉树的最大深度

我的思路:dfs水题

我的代码:

class Solution {
public:
    int ans = 0;
    void dfs(TreeNode* root, int depth) {
        if (root->left == NULL && root->right == NULL) {
            ans = max(ans, depth+1);
            return;
        }
        if (root->left) dfs(root->left, depth+1);
        if (root->right) dfs(root->right, depth+1);
    }
    int maxDepth(TreeNode* root) {
        if (root) dfs(root, 0);
        return ans;
    }
};
View Code

九章最优解:同样dfs, 没人家写得好

class Solution {
public:
    /**
     * @param root: The root of binary tree.
     * @return: An integer
     */
    int maxDepth(TreeNode *root) {
        if (root == NULL) {
            return 0;
        }
        int left = maxDepth(root->left);
        int right = maxDepth(root->right);
        return left > right ? left + 1 : right + 1;
    }
};
View Code

105. Construct Binary Tree from Preorder and Inorder Traversal

题意:由前序、中序遍历生成二叉树

我的思路:dfs寻找每个节点的前序、中序遍历,递归生成 

我的代码:

/**
 * 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:
    void dfs(TreeNode* root, vector<int>& preorder, vector<int>& inorder, int f1, int t1, int f2, int t2) {
         root->val = preorder[f1];
         int i;
         for (i = f2; i <= t2; i++) {
             if (inorder[i] == preorder[f1]) break;
         }
         if (i > f2) root->left  = new TreeNode(0), dfs(root->left, preorder, inorder, f1+1, i+f1-f2, f2, i-1);
         if (i < t2) root->right  = new TreeNode(0), dfs(root->right, preorder, inorder, t1-t2+i+1, t1, i+1, t2);
         return;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        TreeNode* root;
        if (preorder.size() == 0) return root;
        root  = new TreeNode(0);
        dfs(root, preorder, inorder, 0, preorder.size()-1, 0, inorder.size()-1);
        cout<<root->val<<endl;
        return root;
    }
};
View Code

九章最优解:思路一样,写法完爆

class Solution {
    /**
     *@param preorder : A list of integers that preorder traversal of a tree
     *@param inorder : A list of integers that inorder traversal of a tree
     *@return : Root of a tree
     */
public:
    typedef vector<int>::iterator Iter;
    TreeNode *buildTreeRecur(Iter istart, Iter iend, Iter pstart, Iter pend)
    {
        if(istart == iend)return NULL;
        int rootval = *pstart;
        Iter iterroot = find(istart, iend, rootval);
        TreeNode *res = new TreeNode(rootval);
        res->left = buildTreeRecur(istart, iterroot, pstart+1, pstart+1+(iterroot-istart));
        res->right = buildTreeRecur(iterroot+1, iend, pstart+1+(iterroot-istart), pend);
        return res;
    }
    TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
        // write your code here
        return buildTreeRecur(inorder.begin(), inorder.end(), preorder.begin(), preorder.end());
    }
};
View Code

106. Construct Binary Tree from Inorder and Postorder Traversal

题意:由中序后序遍历恢复二叉树

我的思路:dfs,跟上题一样

/**
 * 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:
    typedef vector<int>::iterator Iter;
    TreeNode *dfs(Iter istart, Iter iend, Iter pstart, Iter pend) {
        if (istart == iend) return NULL;
        int val = *(pend-1);
        Iter root = find(istart, iend, val);
        TreeNode *res = new TreeNode(val);
        res->left = dfs(istart, root, pstart, pstart+(root-istart));
        res->right = dfs(root+1, iend, pstart+(root-istart), pend-1);
        return res;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        return dfs(inorder.begin(), inorder.end(), postorder.begin(), postorder.end());
    }
};
View Code

九章最优解:一样

108. Convert Sorted Array to Binary Search Tree

题意:将有序数列转化为二分搜索树

我的思路:dfs1A 

我的代码:

/**
 * 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* dfs(vector<int>& nums, int f, int t) {
        int mid = (f+t)/2;
        TreeNode* ret = new TreeNode(nums[mid]);
        if (mid > f) ret->left = dfs(nums, f, mid-1);
        if (mid < t) ret->right = dfs(nums, mid+1, t);
        return ret;
    }
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        if (nums.size() == 0) return NULL;
        return dfs(nums, 0, nums.size()-1);
    }
};
View Code

九章最优解:一样

111. Minimum Depth of Binary Tree

题意:求二叉树的最小深度,即根节点到叶子结点的最小距离

我的思路:bfs水题

我的代码:

class Solution {
public:
    int minDepth(TreeNode* root) {
        if (root == NULL) return 0;
        int ans = 0, flag = 1;
        queue<TreeNode*> que;
        que.push(root);
        while (flag) {
            int cnt = que.size();
            ans++;
            while (cnt--) {
                TreeNode* tmp = que.front();
                que.pop();
                if (tmp->left == NULL && tmp->right == NULL) {
                    flag = 0;
                    break;
                }
                if (tmp->left) que.push(tmp->left);
                if (tmp->right) que.push(tmp->right);
            }
        }
        return ans;
    }
};
View Code

九章最优解:dfs,递归返回左子树和右子树深度较小的

class Solution {
public:
    /**
     * @param root: The root of binary tree.
     * @return: An integer
     */
    int ans;
    int solve_dp(TreeNode *root) {
        if(root == NULL)
            return 0;   

        if (root->left == NULL && root->right == NULL)
            return 1;
 
        int lf = 0x7fffffff, rt = 0x7fffffff;
        if(root->left)
            lf = solve_dp(root->left);
         
        if(root->right) 
            rt = solve_dp(root->right);

        return min(lf, rt) + 1;
    }
    int minDepth(TreeNode *root) {
        // write your code here
        if (!root) return 0;
        return solve_dp(root);
    }
};
View Code

112. Path Sum

题意:求是否有根节点到叶子结点的值之和为sum

我的思路:dfs1A,但是写的很不好

我的代码:

class Solution {
public:
    bool dfs(TreeNode* root, int sum, int tmp) {
        tmp += root->val;
        if (root->left == NULL && root->right == NULL && tmp == sum) return 1;
        if (root->left && root->right) return dfs(root->left, sum, tmp) || dfs(root->right, sum, tmp);
        else if (root->left) return dfs(root->left, sum, tmp);
        else if (root->right) return dfs(root->right, sum, tmp);
        return 0;
    }
    bool hasPathSum(TreeNode* root, int sum) {
        if (root == NULL) return 0;
        return dfs(root, sum, 0);
    }
};
View Code

九章最优解:

public class Solution {
    public boolean hasPathSum(TreeNode root, int sum) {
        if (root == null) {
            return false;
        }
        if (root.left == null && root.right == null) {
            return sum == root.val;
        }
        return hasPathSum (root.left, sum - root.val)
            || hasPathSum(root.right, sum - root.val);
    }
}
View Code

113. Path Sum II

题意:返回根节点到叶节点值之和为sum的所有路径

我的思路:dfs1A

我的代码:

class Solution {
public:
    vector<vector<int>> ans;
    void dfs(TreeNode* root, int sum, int cnt, vector<int> tmp) {
        cnt += root->val;
        tmp.push_back(root->val);
        if (root->left == NULL && root->right == NULL && cnt == sum) ans.push_back(tmp);
        if (root->left) dfs(root->left, sum, cnt, tmp);
        if (root->right) dfs(root->right, sum, cnt, tmp);
    }
    vector<vector<int>> pathSum(TreeNode* root, int sum) {
        if (root == NULL) return ans;
        vector<int> tmp;
        dfs(root, sum, 0, tmp);
        return ans;
    }
};
View Code

九章最优解:思路一样,代码只有java的

public class Solution {
    public ArrayList<ArrayList<Integer>> pathSum(TreeNode root, int sum) {
        ArrayList<ArrayList<Integer>> rst = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> solution = new ArrayList<Integer>();

        findSum(rst, solution, root, sum);
        return rst;
    }

    private void findSum(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> solution, TreeNode root, int sum){
        if (root == null) {
            return;
        }

        sum -= root.val;

        if (root.left == null && root.right == null) {
            if (sum == 0){
                solution.add(root.val);
                result.add(new ArrayList<Integer>(solution));
                solution.remove(solution.size()-1);
            }
            return;
        }

        solution.add(root.val);
        findSum(result, solution, root.left, sum);
        findSum(result, solution, root.right, sum);
        solution.remove(solution.size()-1);
    }
}
View Code

129. Sum Root to Leaf Numbers

题意:每个从根到叶的路径生成一个数,根是高位,求这些数的和

我的思路:递归水题1A

我的代码:

class Solution {
public:
    int ans;
    void dfs(TreeNode* root, int tmp) {
        tmp = tmp*10+root->val;
        if (root->left == NULL && root->right == NULL) {
            ans += tmp;
            return;
        }
        if (root->left) dfs(root->left, tmp);
        if (root->right) dfs(root->right, tmp);
    }
    int sumNumbers(TreeNode* root) {
        if (root == NULL) return 0;
        dfs(root, 0);
        return ans;
    }
};
View Code

199. Binary Tree Right Side View

题意:给定一棵二叉树,输出从右往左看到的数字

我的思路:dfs,记录层数,先dfs右子树,再dfs左子树

我的代码:

class Solution {
public:
    void dfs(TreeNode* root, vector<int> &ans, int i) {
        if (i > ans.size()) ans.push_back(root->val);
        if (root->right) dfs(root->right, ans, i+1);
        if (root->left) dfs(root->left, ans, i+1);
    }
    vector<int> rightSideView(TreeNode* root) {
        vector<int> ans;
        if (root) dfs(root, ans, 1);
        return ans;
    }
};
View Code

222. Count Complete Tree Nodes

题意:数完全二叉树的节点数

我的思路:dfs,bfs都会超时,要利用完全二叉树节点数的特点,递归找左右子树深度相同的子树可以直接计算出个数

我的代码:

class Solution {
public:
    int countNodes(TreeNode* root) {
        if (!root) return 0;
        int l = 1, r = 1;
        TreeNode* r1 = root, *r2 = root;
        while (r1->left) {
            l++;
            r1 = r1->left;
        }
        while (r2->right) {
            r++;
            r2 = r2->right;
        }
        if (l == r) return pow(2, l)-1;
        return 1+countNodes(root->left)+countNodes(root->right);
    }
};
View Code

226. Invert Binary Tree

题意:翻转一棵二叉树

我的思路:

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == NULL) return root;
        TreeNode* tmp = root->right;
        root->right = root->left;
        root->left = tmp;
        if (root->left) invertTree(root->left);
        if (root->right) invertTree(root->right);
        return root;
    }
};
View Code

230. Kth Smallest Element in a BST

题意:输出二叉搜索树中第k小的数

我的思路:利用BST的中序遍历是一个递增序列,dfs

我的代码:

class Solution {
public:
    int cnt, ans;
    void dfs(TreeNode* root, int k) {
        if (root->left) dfs(root->left, k);
        cnt++;
        if (cnt == k) {
            ans = root->val;
            return;
        }
        if (root->right) dfs(root->right, k);
    }
    int kthSmallest(TreeNode* root, int k) {
        if (root) dfs(root, k);
        return ans;
    }
};
View Code

235. Lowest Common Ancestor of a Binary Search Tree

题意:给定一棵二叉搜索树,及两个节点,输出两节点最近祖先的值

我的思路:第一个在两个值之间的节点就是他俩的最近祖先

我的代码:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (p->val > q->val) {
            TreeNode* tmp = q;
            q = p;
            p = tmp;
        }
        while (root) {
            if (root->val >= p->val && root->val <= q->val) return root;
            else if (root->val > q->val) root = root->left;
            else root = root->right;
        }
    }
};
View Code

236. Lowest Common Ancestor of a Binary Tree

题意:返回二叉树的最低祖先

我的思路:递归检查

我的代码:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (!root || root == p || root == q) return root;
        TreeNode* l = lowestCommonAncestor(root->left, p, q);
        TreeNode* r = lowestCommonAncestor(root->right, p, q);
        if (l && r) return root;
        return l == NULL ? r : l;
    }
};
View Code

297. Serialize and Deserialize Binary Tree

题意:将一棵二叉树编成一个序列并且能够解码

我的思路:前序遍历编码,dfs解码

我的代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        if (root == NULL) return "#";
        return to_string(root->val)+","+serialize(root->left)+","+serialize(root->right);
    }

    // Decodes your encoded data to tree.
    TreeNode* reconduct(string &data) {
        if (data[0] == '#') {
            if (data.size() > 1) data = data.substr(2);
            return NULL;
        }
        int i = 0, n = 0;
        if (isdigit(data[i]) || data[i] == '-') {
            int k = 1;
            if (data[i] == '-') k = -1, i++;
            while (isdigit(data[i])) {
                n = n*10+data[i]-'0';
                i++;
            }
            n = n*k;
        }
        TreeNode* ret = new TreeNode(n);
        data = data.substr(i+1);
        ret->left = reconduct(data);
        ret->right = reconduct(data);
        return ret;
    }
    TreeNode* deserialize(string data) {      
        return reconduct(data);
    }
};

// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));
View Code

310. Minimum Height Trees

题意:给定一个无向图,不含重边,输出使它成为高度最小的树的根节点

思路:discuss第一个,bfs

我的代码:

class Solution {
public:
    vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
        if (n == 1) return {0};
        vector<unordered_set<int>> e(n);
        vector<unordered_set<int>::iterator> it(n);
        for (int i = 0; i < edges.size(); i++) {
            e[edges[i].first].insert(edges[i].second);
            e[edges[i].second].insert(edges[i].first);
        }
        vector<int> ans;
        for (int i = 0; i < n; i++) {
            it[i] = e[i].begin();
            if (e[i].size() == 1) ans.push_back(i);
        }
        while (n > 2) {
            n -= ans.size();
            vector<int> tmp;
            for (int i : ans)
                for (int j : e[i]) {
                    e[j].erase(i);
                    if (e[j].size() == 1) tmp.push_back(j);
                }
            ans = tmp;
        }
        return ans;
    }
};
View Code

337. House Robber III

题意:从树上取值,不能去相邻节点,求可以取得的总数最大值

我的思路:dfs,每个节点记录有他的最大值和没他的最大值两个数,最后输出根节点两个值中较大的

我的代码:

class Solution {
public:
    vector<int> dfs(TreeNode* root) {
        vector<int> ans(2, 0);
        if (!root) return ans;
        vector<int> tmp1 = dfs(root->left), tmp2 = dfs(root->right);
        ans[0] = max(tmp1[0], tmp1[1])+max(tmp2[0], tmp2[1]);
        ans[1] = tmp1[0]+tmp2[0]+root->val;
        return ans;
    }
    int rob(TreeNode* root) {
        vector<int> ans = dfs(root);
        return max(ans[0], ans[1]);
    }
};
View Code

437. Path Sum III

题意:输出树有几条从上(不一定是根节点)到下(不一定是叶子)的路径和为sum

我的思路:dfs

我的代码:

class Solution {
public:
    int dfs(TreeNode* root, int sum) {
        if (root == NULL) return 0;
        return (sum == root->val)+dfs(root->left, sum-root->val)+dfs(root->right, sum-root->val); 
    }
    int pathSum(TreeNode* root, int sum) {
        if (root == NULL) return 0;
        return pathSum(root->left, sum)+pathSum(root->right, sum)+dfs(root, sum);
    }
};
View Code

449. Serialize and Deserialize BST

题意:将排序二叉树序列化、解序列化

我的思路:跟297题用的一份代码

我的代码:

class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        if (root == NULL) return "#";
        return to_string(root->val)+","+serialize(root->left)+","+serialize(root->right);
    }

    // Decodes your encoded data to tree.
    TreeNode* reconduct(string &data) {
        if (data[0] == '#') {
            if (data.size() > 1) data = data.substr(2);
            return NULL;
        }
        int i = 0, n = 0;
        if (isdigit(data[i]) || data[i] == '-') {
            int k = 1;
            if (data[i] == '-') k = -1, i++;
            while (isdigit(data[i])) {
                n = n*10+data[i]-'0';
                i++;
            }
            n = n*k;
        }
        TreeNode* ret = new TreeNode(n);
        data = data.substr(i+1);
        ret->left = reconduct(data);
        ret->right = reconduct(data);
        return ret;
    }
    TreeNode* deserialize(string data) {
        return reconduct(data);
    }
};
View Code

450. Delete Node in a BST

题意:删除二叉搜索树中等于某个值的节点

我的思路:递归

我的代码:

class Solution {
public:
    int findmin(TreeNode* root) {
        while (root->left) root = root->left;
        return root->val;
    }
    TreeNode* deleteNode(TreeNode* root, int key) {
        if (root == NULL) return root;
        if (root->val > key) root->left = deleteNode(root->left, key);
        else if (root->val < key) root->right = deleteNode(root->right, key);
        else {
            if (root->left == NULL) return root->right;
            if (root->right == NULL) return root->left;
            root->val = findmin(root->right);
            root->right = deleteNode(root->right, root->val);
        }
        return root;
    }
};
View Code

530. Minimum Absolute Difference in BST

题意:输出二叉搜索树任意两节点间的最小差值的绝对值

我的思路:每个节点找比他小的最大的和比他大的最小的,结果是二者之一

我的代码:

class Solution {
public:
    int getmax(TreeNode* root) {
        while (root->right) root = root->right;
        return root->val;
    }
    int getmin(TreeNode* root) {
        while (root->left) root = root->left;
        return root->val;
    }
    void dfs(TreeNode* root, int& ans) {
        if (!root) return;
        if (root->left) {
            ans = min(ans, abs(getmax(root->left)-root->val));
            dfs(root->left, ans);
        }
        if (root->right) {
            ans = min(ans, abs(root->val-getmin(root->right)));
            dfs(root->right, ans);
        }
    }
    int getMinimumDifference(TreeNode* root) {
        int ans = 0x7fffffff;
        dfs(root, ans);
        return ans;
    }
};
View Code

501. Find Mode in Binary Search Tree

题意:找出二叉搜索树中频率最高的数,要求空间复杂度O1

我的思路:中序遍历

我的代码:

 

class Solution {
public:
    TreeNode* pre = NULL;
    void dfs(TreeNode* root, vector<int>& ans, int& cnt, int& maxn) {
        if (!root) return;
        if (root->left) dfs(root->left, ans, cnt, maxn);
        if (pre != NULL) {
            if (root->val == pre->val) cnt++;
            else cnt = 1;
        }
        if (cnt >= maxn) {
            if (cnt > maxn) ans.clear();
            ans.push_back(root->val);
            maxn = cnt;
        }
        pre = root;
        if (root->right) dfs(root->right, ans, cnt, maxn);
    }
    vector<int> findMode(TreeNode* root) {
        vector<int> ans;
        if (!root) return ans;
        int cnt = 1, maxn = 0;
        dfs(root, ans, cnt, maxn);
        return ans;
    }
};

538. Convert BST to Greater Tree

题意:将一个二叉搜索树的每个节点值加上所有大于他的值

我的思路:dfs

我的代码:

class Solution {
public:
    int sum;
    void dfs(TreeNode* root) {
        if (root->right) dfs(root->right);
        sum += root->val;
        root->val = sum;
        if (root->left) dfs(root->left);
    }
    TreeNode* convertBST(TreeNode* root) {
        if (root == NULL) return root;
        dfs (root);
        return root;
    }
};
View Code

九章最优解:一样

563. Binary Tree Tilt

题意:常规dfs 

题意:判断一个树是否是另一个树的子树

我的思路:递归

我的代码:

View Code

617. Merge Two Binary Trees

题意:将两棵二叉树的节点值相加,不同的边补出

我的思路:蜜汁通过

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        if (t1 && t2) {
            t1->val += t2->val;
            t1->left = mergeTrees(t1->left, t2->left);
            t1->right = mergeTrees(t1->right, t2->right);
        } else if (t1 == NULL && t2) t1 = t2;
        return t1;
    }
};
View Code

solution解法:差不多

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        if (!t2)
            return t1;
        if (!t1)
            return t2;
        t1->val += t2->val;
        t1->left = mergeTrees(t1->left, t2->left);
        t1->right = mergeTrees(t1->right, t2->right);
        return t1;
    }
};
View Code

637. Average of Levels in Binary Tree

题意:输出二叉树每一层的平均值

我的思路:bfs

我的代码:

class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        vector<double> ans;
        if (root == NULL) return ans;
        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            ans.push_back(0);
            int n = q.size(), m = ans.size();
            for (int i = 0; i < n; i++) {
                TreeNode* tmp = q.front();
                q.pop();
                ans[m-1] += tmp->val;
                if (tmp->left) q.push(tmp->left);
                if (tmp->right) q.push(tmp->right);
            }
            ans[m-1] /= n;
        }
        return ans;
    }
};
View Code

655. Print Binary Tree

题意:将二叉树打印为二维矩阵

我的思路:先bfs求个层数,就知道了矩阵维度,再dfs改变矩阵元素

我的代码:

class Solution {
public:
    void dfs(TreeNode* root, vector<vector<string>>& ans, int l, int f, int t) {
        ans[l][(f+t)/2] = to_string(root->val);
        if (root->left) dfs(root->left, ans, l+1, f, (f+t)/2-1);
        if (root->right) dfs(root->right, ans, l+1, (f+t)/2+1, t);
    }
    vector<vector<string>> printTree(TreeNode* root) {
        if (!root) return {{""}};
        int depth = 0;
        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            int n = q.size();
            depth++;
            for (int i = 0; i < n; i++) {
                TreeNode* tmp = q.front();
                q.pop();
                if (tmp->left) q.push(tmp->left);
                if (tmp->right) q.push(tmp->right);
            }
        }
        vector<vector<string>> ans(depth, vector<string>(pow(2, depth)-1));
        dfs(root, ans, 0, 0, pow(2, depth)-2);
        return ans;
    }
};
View Code

662. Maximum Width of Binary Tree

题意:输出二叉树的最大宽度,宽度即每层最左节点到最右节点

我的思路:只需要按照完全二叉树节点的计数方法保存每个节点在整棵二叉树中的位置下标,一般当前位置是i,则其左孩子节点的下标为2*i,其右孩子下标为2*i+1。所以最后只需要将每一层中最大的孩子的下标数-开始的最小孩子的下标数,就是最大宽度,采用层次遍历的方法来执行即可。

我的代码:

class Solution {
public:
    int widthOfBinaryTree(TreeNode* root) {
        if (!root) return 0;
        queue<TreeNode*> qr;
        vector<int> qn;
        int ans = 1;
        qr.push(root);
        qn.push_back(1);
        while (!qr.empty()) {
            ans = max(ans, qn[qn.size()-1]-qn[0]+1);
            int n = qr.size();
            for (int i = 0; i < n; i++) {
                TreeNode* tmp = qr.front();
                qr.pop();
                int id = qn[0];
                qn.erase(qn.begin());
                if (tmp->left) {
                    qr.push(tmp->left);
                    qn.push_back(id<<1);
                }
                if (tmp->right) {
                    qr.push(tmp->right);
                    qn.push_back(id<<1|1);
                }
            }
        }
        return ans;
    }
};
View Code

 

posted @ 2017-03-24 15:51  Silence、  阅读(170)  评论(0编辑  收藏  举报