代码随想录训练营Day14|树:层序遍历(十道题)、226.翻转二叉树、101.对称二叉树

文章对比了ArrayList和LinkedList在Java中的实现和适用场景,ArrayList适合随机访问,LinkedList适合插入和删除。同时,提供了LeetCode中二叉树层序遍历问题的解决方案,包括正常遍历、反向遍历和获取右视图的方法。
摘要由CSDN通过智能技术生成

注意:
ArrayList、List和LinkedList都是Java中常见的集合类,它们的主要区别如下:

  1. ArrayList是一个动态数组类,它实现了List接口。它通过数组来存储元素,支持快速随机访问。ArrayList的缺点是在插入和删除元素时,需要对后面的元素进行移动,因此效率较低。但是,在对集合进行频繁的随机访问时,ArrayList的性能要优于LinkedList。
  2. LinkedList是一个双向链表类,它同样实现了List接口。它通过链表来存储元素,支持快速的插入和删除操作。LinkedList的缺点是访问任意位置的元素时需要从头或从尾部遍历链表,因此效率较低。但是,在对集合进行频繁的插入和删除操作时,LinkedList的性能要优于ArrayList。
  3. List是一个接口,它定义了访问列表元素的基本操作,如添加元素、获取元素、删除元素等。List接口的实现类包括ArrayList、LinkedList等。List接口提供了一些额外的操作,如获取子列表、查找元素位置等。

综上所述,ArrayList和LinkedList都实现了List接口,但是它们的内部实现不同,适用于不同的场景。在需要频繁进行随机访问的情况下,ArrayList的性能更好;在需要频繁进行插入和删除操作的情况下,LinkedList的性能更好。List接口提供了一些基本的操作,可以方便地对集合进行操作。在实际应用中,需要根据具体场景选择合适的集合类。

层序遍历

LeetCode102:二叉树的层序遍历

二叉树的层序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> ans = new ArrayList<List<Integer>>();     // 这个ans要加个public ,不然在getAns里面调用不到。

    public List<List<Integer>> levelOrder(TreeNode root) {
        // 广度优先算法
        // 需要一个flag用来记录是哪一层,也就是表示要弹出这一层
        // 递归法不太好理解,借助队列迭代好理解
        getAns(root);
        return ans;
    }

    public void getAns(TreeNode node){
        if(node == null){
            return;
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(node);
        while(!queue.isEmpty()){
            List<Integer> ans_ = new ArrayList<Integer>();
            int len = queue.size(); // 用来标记这一层有多少个node
            while(len>0){
                TreeNode temp = queue.poll();
                ans_.add(temp.val);
                if(temp.left != null){
                    queue.offer(temp.left); // 队列,先进先出。所以left在前面
                }
                if(temp.right != null){
                    queue.offer(temp.right);
                }
                len--;
            }
        ans.add(ans_);
        }
    }
}

C++的代码还是要熟悉,里面的元素的

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> ans;    
        if(root == NULL) return ans;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()){
            int size = que.size(); // 要先将这一层的元素个数取出来,用于下面的遍历边界
            vector<int> ans_;
            for(int i=0;i<size;i++){
                TreeNode* node = que.front();
                ans_.push_back(node->val);
                que.pop();
                if(node->left) que.push(node->left); // 就是因为这里会改变que的长度,所以在一开始的时候就要确定好size
                if(node->right) que.push(node->right);
            }
            ans.push_back(ans_);
        }
        return ans;
    }
};

LeetCode107:二叉树的层序遍历 ②

思路:得到从上到下的层序遍历之后,再将ans 翻转

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> ans = new ArrayList<List<Integer>>();
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        getAns(root);
        Collections.reverse(ans);// 得到从上到下的层序遍历之后,再将ans 翻转
        return ans;
    }

    public void getAns(TreeNode node){
        if(node == null){
            return;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(node);
        while(!queue.isEmpty()){
            List<Integer> ans_ = new ArrayList<>();
            int len = queue.size();
            while(len>0){
                TreeNode temp = queue.poll();
                ans_.add(temp.val);
                // 注意 不用将left 和right颠倒,这是队列,
                if(temp.left != null){
                    queue.offer(temp.left);
                }
                if(temp.right != null){
                    queue.offer(temp.right);
                }
                
                len--;
            }
            ans.add(ans_);
        }

    }
}
class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        vector<vector<int>> ans;
        if(root == NULL) return ans;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()){
            int size = que.size();
            vector<int> ans_;
            for(int i=0;i<size;i++){
                TreeNode* node = que.front();
                que.pop();
                ans_.push_back(node->val);
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
            ans.push_back(ans_);
        }
        reverse(ans.begin(), ans.end()); // 翻转一下
        return ans;
        // 不可以写成 return reverse(ans.begin(), ans.end()); 
        // 因为reverse只是翻转 不会返回反转之后的ans
    }
};

LeetCode199:二叉树的右视图

思路:只将当前层的最后一个元素放到ans里面。size是用来记录当前层一共有多少个元素的,所以只要当size==1 到了最后一个元素时,将他记录到ans就可以。
关键点:注意右视图,不是仅返回右侧的右节点。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        // 右视图 不是只返回右节点
        // 最右边只有左节点的情况也是可以看到左节点的。
        List<Integer> ans = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        if(root == null){
            return ans;
        }
        queue.offer(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            while(size>0){
                TreeNode temp = queue.poll();
                if(temp.left != null){
                    queue.offer(temp.left);
                }
                if(temp.right != null){
                    queue.offer(temp.right);
                }
                if(size==1){
                    ans.add(temp.val);
                }
                size--;
            }
        }
        return ans;
    }
}
class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        vector<int> ans;
        if(root == NULL) return ans;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()){
            int size = que.size();
            for(int i=0;i<size;i++){
                TreeNode* node = que.front();
                if(size-i==1) ans.push_back(node->val);
                que.pop();
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
        return ans;
    }
};

后续再补

LeetCode226:翻转二叉树

思路:这一题本质还是遍历。递归法遍历的时候加一个交换左右子节点的步骤即可

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode invertTree(TreeNode root) {
        // 递归
        if(root == null){
            return root;
        }
        TreeNode left = root.left;
        TreeNode right = root.right;
        swap(root);
        invertTree(left);
        invertTree(right);
        return root;
    }
    public void swap(TreeNode root){
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

迭代:
注意:这里是返回的root因此不能像之前的层序遍历那样自己建立数组用于返回。而且在对node左右节点交换是,也不是将queue里面换个位置就可以了。而是要swap(node->left,node->right)。

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        
        if(root == NULL) return root;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()){
            int size = que.size();
            for(int i=0;i<size;i++){
                TreeNode* node = que.front();
                que.pop();
                swap(node->left, node->right);
                // 因为返回的是root而不是自己定义的数组,因此这里必须对node操作交换左右节点。
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
        return root;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值