leetcode刷题——数据结构(2):树

递归(2.22)

1. 树的高度

第一次可做出Ok

 

2. 平衡树

思考后可做出Ok

 

3. 两节点的最长路径

思考后可做出

 

4. 翻转树

修改后可做出

 

5. 归并两棵树

第一次可做出Ok

 

6. 判断路径和是否等于一个数

修改后可做出

 

7. 统计路径和等于一个数的路径数量

第一次未做出

8. 子树

修改后可做出

 

9. 树的对称

第一次可做出Ok

 

10. 最小路径

修改后可做出Ok

 

11. 统计左叶子节点的和

第一次可做出,

解法可简化

12. 相同节点值的最大路径长度

思考后可做出

13. 间隔遍历

第一次可做出Ok

 

14. 找出二叉树中第二小的节点

思考后可做出,

解法可简化

层次遍历

1. 一棵树每层节点的平均数

第一次可做出Ok

 

2. 得到左下角的节点

思考后可做出,

解法可简化

前中后序遍历

1. 非递归实现二叉树的前序遍历

修改后可做出

2. 非递归实现二叉树的后序遍历

思考后可做出Ok

 

3. 非递归实现二叉树的中序遍历

第一次未做出

BST

1. 修剪二叉查找树

第一次可做出Ok

 

2. 寻找二叉查找树的第 k 个元素

思考后可做出,

解法可简化

3. 把二叉查找树每个节点的值都加上比它大的节点的值

第一次可做出Ok

 

4. 二叉查找树的最近公共祖先

第一次可做出Ok

 

5. 二叉树的最近公共祖先

思考后可做出,

解法可简化

6. 从有序数组中构造二叉查找树(2.23)

第一次可做出Ok

 

7. 根据有序链表构造平衡的二叉查找树

思考后可做出,同上

 

8. 在二叉查找树中寻找两个节点,使它们的和为一个给定值

解法可简化

9. 在二叉查找树中查找两个节点之差的最小绝对值

思考后可做出,

解法可简化

10. 寻找二叉查找树中出现次数最多的值

思考后可做出

 

Trie

1. 实现一个 Trie

第一次未做出

2. 实现一个 Trie,用来求前缀和

思考后可做出,类上

 

 递归

一棵树要么是空树,要么有两个指针,每个指针指向一棵树。树是一种递归结构,很多树的问题可以使用递归来处理。

1. 树的高度

104. Maximum Depth of Binary Tree (Easy)

https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/

2. 平衡树

110. Balanced Binary Tree (Easy)

https://leetcode-cn.com/problems/balanced-binary-tree/

3. 两节点的最长路径

543. Diameter of Binary Tree (Easy)

https://leetcode-cn.com/problems/diameter-of-binary-tree/

4. 翻转树

226. Invert Binary Tree (Easy)

https://leetcode-cn.com/problems/invert-binary-tree/

5. 归并两棵树

617. Merge Two Binary Trees (Easy)

https://leetcode-cn.com/problems/merge-two-binary-trees/

6. 判断路径和是否等于一个数

112. Path Sum (Easy)

https://leetcode-cn.com/problems/path-sum/

7. 统计路径和等于一个数的路径数量

437. Path Sum III (Easy)

https://leetcode-cn.com/problems/path-sum-iii/

/**
 * 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:
    int pathStartFrom(TreeNode* root, int sum){
        if(root==NULL) return 0;
        int cur=sum-root->val;
        return pathStartFrom(root->left,cur)+pathStartFrom(root->right,cur)+((cur==0)?1:0);
    }
    int pathSum(TreeNode* root, int sum) {
        if(root==NULL) return 0;
        return pathStartFrom(root,sum)+pathSum(root->left,sum)+pathSum(root->right,sum);
    }
};

8. 子树

572. Subtree of Another Tree (Easy)

https://leetcode-cn.com/problems/subtree-of-another-tree/

9. 树的对称

101. Symmetric Tree (Easy)

https://leetcode-cn.com/problems/symmetric-tree/

10. 最小路径

111. Minimum Depth of Binary Tree (Easy)

https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/

11. 统计左叶子节点的和

404. Sum of Left Leaves (Easy)

https://leetcode-cn.com/problems/sum-of-left-leaves/

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if(root==NULL) return 0;
        if(root->left!=NULL&&root->left->left==NULL&&root->left->right==NULL) 
            return sumOfLeftLeaves(root->right)+root->left->val;
        else 
            return sumOfLeftLeaves(root->right)+sumOfLeftLeaves(root->left);
    }
};

12. 相同节点值的最大路径长度

687. Longest Univalue Path (Easy)

https://leetcode-cn.com/problems/longest-univalue-path/

class Solution {
public:
    int longestPathFromRoot(TreeNode* root,int val){
        if(root==NULL||root->val!=val) return 0;
        return 1+max(longestPathFromRoot(root->left,val),longestPathFromRoot(root->right,val));
    }
    int longestUnivaluePath(TreeNode* root) {
        if(root==NULL) return 0;
        int fr=longestPathFromRoot(root->left,root->val)+longestPathFromRoot(root->right,root->val);
        return max(fr,max(longestUnivaluePath(root->left),longestUnivaluePath(root->right)));
    }
};

13. 间隔遍历

337. House Robber III (Medium)

https://leetcode-cn.com/problems/house-robber-iii/

14. 找出二叉树中第二小的节点

671. Second Minimum Node In a Binary Tree (Easy)

https://leetcode-cn.com/problems/second-minimum-node-in-a-binary-tree/

class Solution {
public:
    int findSecondMinimumValue(TreeNode* root) {
        if(root==NULL||root->left==NULL) return -1;
        int l=(root->left->val==root->val)?findSecondMinimumValue(root->left):root->left->val;
        int r=(root->right->val==root->val)?findSecondMinimumValue(root->right):root->right->val;
        if(l!=-1&&r!=-1) return min(l,r);
        return (l==-1)?r:l;
    }
};

层次遍历

使用 BFS 进行层次遍历。不需要使用两个队列来分别存储当前层的节点和下一层的节点,因为在开始遍历一层的节点时,当前队列中的节点数就是当前层的节点数,只要控制遍历这么多节点数,就能保证这次遍历的都是当前层的节点。

1. 一棵树每层节点的平均数

637. Average of Levels in Binary Tree (Easy)

https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/

2. 得到左下角的节点

513. Find Bottom Left Tree Value (Easy)

https://leetcode-cn.com/problems/find-bottom-left-tree-value/

class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*> q;
        if(root==NULL) return 0;
        q.push(root);
        while(!q.empty()){
            root=q.front();
            q.pop();
            if(root->right!=NULL) q.push(root->right);  //先右后左
            if(root->left!=NULL) q.push(root->left);
        }
        return root->val;       
    }
};

前中后序遍历

层次遍历使用 BFS 实现,利用的就是 BFS 一层一层遍历的特性;而前序、中序、后序遍历利用了 DFS 实现。

前序、中序、后序遍只是在对节点访问的顺序有一点不同,其它都相同。

① 前序
void dfs(TreeNode root) {
    visit(root);
    dfs(root.left);
    dfs(root.right);
}
② 中序
void dfs(TreeNode root) {
    dfs(root.left);
    visit(root);
    dfs(root.right);
}
③ 后序
void dfs(TreeNode root) {
    dfs(root.left);
    dfs(root.right);
    visit(root);
}

1. 非递归实现二叉树的前序遍历

144. Binary Tree Preorder Traversal (Medium)

https://leetcode-cn.com/problems/binary-tree-preorder-traversal/

1.	非递归
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        if(root==NULL) return res;
        stack<TreeNode*> st;
        st.push(root);
        while(!st.empty()){
            root=st.top();
            st.pop();
            res.push_back(root->val);
            if(root->right!=NULL) st.push(root->right); //先右后左,保证左子树先遍历
            if(root->left!=NULL) st.push(root->left);
        }
        return res;
    }
};
2.	递归
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res,l,r;
        if(root==NULL) return res;
        res.push_back(root->val);
        l=preorderTraversal(root->left);
        r=preorderTraversal(root->right);
        for(auto i:l) res.push_back(i);
        for(auto i:r) res.push_back(i);
        return res;
    }
};

2. 非递归实现二叉树的后序遍历

145. Binary Tree Postorder Traversal (Medium)

https://leetcode-cn.com/problems/binary-tree-postorder-traversal/

3. 非递归实现二叉树的中序遍历

94. Binary Tree Inorder Traversal (Medium)

https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

1.	非递归
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> st;
        while(root!=NULL||!st.empty()){
            while(root!=NULL){
                st.push(root);
                root=root->left;
            }
            TreeNode *cur=st.top();
            st.pop();
            res.push_back(cur->val);
            root=cur->right;
        }
        return res;
    }
};
2.	递归
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> l,r;
        if(root==NULL) return l;
        l=inorderTraversal(root->left);
        l.push_back(root->val);
        r=inorderTraversal(root->right);
        for(int i:r) l.push_back(i);
        return l;
    }
};

BST

二叉查找树(BST):根节点大于等于左子树所有节点,小于等于右子树所有节点。

二叉查找树中序遍历有序。

1. 修剪二叉查找树

669. Trim a Binary Search Tree (Easy)

https://leetcode-cn.com/problems/trim-a-binary-search-tree/

2. 寻找二叉查找树的第 k 个元素

230. Kth Smallest Element in a BST (Medium)

https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst/

可采用中序遍历
1.	递归
class Solution {
public:
    void inOrder(TreeNode* root,int& k,int& val){
        if(root==NULL) return;
        inOrder(root->left,k,val);
        k--;
        if(k==0) val=root->val;
        inOrder(root->right,k,val);
    }
    int kthSmallest(TreeNode* root, int k) {
        int res=0;
        inOrder(root,k,res);
        return res;
    }
};
2.	非递归
class Solution {
public:
    int kthSmallest(TreeNode* root, int k) {
        stack<TreeNode*> st;
        while(root!=NULL||!st.empty()){
            while(root!=NULL){
                st.push(root);
                root=root->left;
            }
            TreeNode* cur=st.top();
            if(k==1) return cur->val;
            k--;
            st.pop();
            root=cur->right;
        }
        return 0;
    }
};
3.	递归解法二
class Solution {
public:
    int NumOfElem(TreeNode* root){
        if(root==NULL) return 0;
        return 1+NumOfElem(root->left)+NumOfElem(root->right);
    }
    int kthSmallest(TreeNode* root, int k) {
        int l=NumOfElem(root->left);
        if(l==k-1) return root->val;
        else if(l<k-1) return kthSmallest(root->right,k-l-1);
        else return kthSmallest(root->left,k);
    }
};

3. 把二叉查找树每个节点的值都加上比它大的节点的值

538. Convert BST to Greater Tree (Easy)

https://leetcode-cn.com/problems/convert-bst-to-greater-tree/

4. 二叉查找树的最近公共祖先

235. Lowest Common Ancestor of a Binary Search Tree (Easy)

https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/

5. 二叉树的最近公共祖先

236. Lowest Common Ancestor of a Binary Tree (Medium)

https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

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

6. 从有序数组中构造二叉查找树

108. Convert Sorted Array to Binary Search Tree (Easy)

https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/

7. 根据有序链表构造平衡的二叉查找树

109. Convert Sorted List to Binary Search Tree (Medium)

https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/

8. 在二叉查找树中寻找两个节点,使它们的和为一个给定值

653. Two Sum IV - Input is a BST (Easy)

https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst/

1.	中序遍历
class Solution {
public:
    void inOrder(TreeNode* root,vector<int>& ret){
        if(root==NULL) return;
        inOrder(root->left,ret);
        ret.push_back(root->val);
        inOrder(root->right,ret);
    }
    bool findTarget(TreeNode* root, int k) {
        vector<int> ret;
        inOrder(root,ret);
        int left=0,right=ret.size()-1;
        while(left<right){
            if(ret[left]+ret[right]==k) return true;
            else if(ret[left]+ret[right]>k) right--;
            else left++;
        }
        return false;        
    }
};
2.	多个递归(不推荐)
class Solution {
public:
    bool findSumFromTwoT(TreeNode* l,TreeNode* r,int k){
        if(l==NULL||r==NULL) return false;
        if(l->val+r->val==k) return true;
        else if(l->val+r->val>k) return findSumFromTwoT(l->left,r,k)||findSumFromTwoT(l,r->left,k);
        else return findSumFromTwoT(l->right,r,k)||findSumFromTwoT(l,r->right,k);
    }
    bool findExistK(TreeNode* root,int k){
        if(root==NULL) return false;
        if(root->val==k) return true;
        else if(root->val<k) return findExistK(root->right,k);
        else return findExistK(root->left,k);
    }
    bool findTarget(TreeNode* root, int k) {
        if(root==NULL) return false;
        int val=k-root->val;
        if(val<=root->val&&findExistK(root->left,val)) return true;
        if(val>root->val&&findExistK(root->right,val)) return true;
        return findSumFromTwoT(root->left,root->right,k)||findTarget(root->left,k)||findTarget(root->right,k);      
    }
};

9. 在二叉查找树中查找两个节点之差的最小绝对值

530. Minimum Absolute Difference in BST (Easy)

https://leetcode-cn.com/problems/minimum-absolute-difference-in-bst/

1.	中序求出序列,再求最小差值
2.	直接中序遍历求最小差值
class Solution {
public:
    void inOrder(TreeNode* root,TreeNode* &pre,int& ret){
        if(root==NULL) return;
        inOrder(root->left,pre,ret);
        if(pre!=NULL) ret=min(ret,root->val-pre->val);
        pre=root;
        inOrder(root->right,pre,ret);
    }
    int getMinimumDifference(TreeNode* root) {
        int ret=INT_MAX;
        TreeNode* pre=NULL;
        inOrder(root,pre,ret);
        return ret;
    }
};

10. 寻找二叉查找树中出现次数最多的值

501. Find Mode in Binary Search Tree (Easy)

https://leetcode-cn.com/problems/find-mode-in-binary-search-tree/

Trie

Trie,又称前缀树或字典树,用于判断字符串是否存在或者是否具有某种字符串前缀。

1. 实现一个 Trie

208. Implement Trie (Prefix Tree) (Medium)

https://leetcode-cn.com/problems/implement-trie-prefix-tree/

class Trie {
private:
    bool isEnd;
    Trie* next[26];
public:
    /** Initialize your data structure here. */
    Trie() {
        isEnd=false;
        memset(next,0,sizeof(next));
    }

    /** Inserts a word into the trie. */
    void insert(string word) {
        Trie* node=this;
        for(auto c:word){
            if(node->next[c-'a']==NULL)
                node->next[c-'a']=new Trie();
            node=node->next[c-'a'];
        }
        node->isEnd=true;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        Trie* node=this;
        for(auto c:word){
            if(node->next[c-'a']==NULL) return false;
            node=node->next[c-'a'];
        }
        return node->isEnd;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        Trie* node=this;
        for(auto c:prefix){
            if(node->next[c-'a']==NULL) return false;
            node=node->next[c-'a'];
        }
        return true;
    }
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie* obj = new Trie();
 * obj->insert(word);
 * bool param_2 = obj->search(word);
 * bool param_3 = obj->startsWith(prefix);
 */

2. 实现一个 Trie,用来求前缀和

677. Map Sum Pairs (Medium)

https://leetcode-cn.com/problems/map-sum-pairs/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值