每日一题算法:2020年5月31日对称二叉树isSymmetric(递归算法)

2020年5月31日对称二叉树isSymmetric

每日一题算法:2020年5月31日对称二叉树isSymmetric(递归算法)_第1张图片

默认格式:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        
    }
}

今天是五月最后一天了,我刷题目也刷了三个礼拜了,学而不思则罔,先对这个月的学习做一个总结。以及以后要做出什么学习方式上的改变。

这三周下来,我发现,光会做题目是没有用的,要学会使用题目中最优的算法的思路,我目前还是处于初学状态,首先应该对所有的基础算法有一个认识,在遇到没有用过的算法的题目的时候,就应该专门将其作为样例来学习这个新的算法,然后写下自己的理解,而不能只是听懂了这个算法什么意思,要思考这个算法能用在什么地方。这也是我下一个阶段的主要目的,学习基础算法。

在题目方面,我觉得简单的题目更适合学习算法,也就是在下一个月,我应该会花更多的时间研究简单的题目的不同做法,如果遇到了困难难度的题目,在没有好的思路的情况下,为了不浪费时间,我选择直接使用暴力算法解决。暴力算法也能够帮助我们整理思路,但是在暴力解决之后,我们任然需要去学习给出的优秀的算法。

对于简单的题目,应该追求一次通过,没有bug,应该考虑到所有可能出现的情况,并且对其进行处理。

好了,开始做今天的题目。

今天的题目难度是简单,所以两种方式,迭代和递归我们都要做一遍

首先先学习一下迭代和递归的区别,递归我是知道的,迭代我只有一个简单的概念,就是在集合里的迭代器,好像和循环差不多的概念,先来学习一下。

迭代算法

迭代算法主要是用新值代替旧值的一种算法,我们主要需要考虑三个方面的问题。

1,迭代变量,就是找到哪一个值是可以迭代的。

2,迭代表达式,旧值和新值之间的关系式。

3,迭代的结束条件,也就是在什么情况下结束迭代

我先用熟悉的递归算法写出代码,然后看一看迭代是怎么完成的

递归算法

递归算法在我看来只有一个特点,A有一个特点,对A进行算法a处理,得到的B任然符合这个特点,对B继续进行算法a处理。直到达成结束条件。

这里很明显,我们先不考虑根节点,从第一级的子节点L1,R1开始

节点L1,R1的特点,L1的左节点值等于R1的右节点值,L1的右节点值等于R1的左节点值

对其进行处理,比较L1的左节点和R1的右节点,L1的右节点和R1的左节点

这时我们比较的对象是L2和R3,L3和R2,他们也符合L1和R1的特点,则任然对其进行该算法处理,直到两个子节点都是空值

我们用代码来实现他。

每日一题算法:2020年5月31日对称二叉树isSymmetric(递归算法)_第2张图片

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
public boolean isSymmetric(TreeNode root) {
            if(root==null)
            return true;
            else if (root.left==null&&root.right==null)
                return true;
            else if (root.left==null||root.right==null){
                return false;
            }
            else {
                if (root.left.val==root.right.val)
                    return isSymmetric(root.left,root.right );
                else 
                    return false;
            }
        }
        //要接受的参数是两个节点,所以重写方法
        public boolean isSymmetric(TreeNode rootL,TreeNode rootR){
            //判断是不是都为空,都为空则表示到达了叶子节点,可以返回了,叶子节点没有子节点,所以肯定对称
            //同时防止空指针异常
            if (rootL.right==null&&rootL.left==null&&rootR.right==null&&rootR.left==null){
                return true;
            }
            //L左和R右为空,L右R左不为空
            else if (rootL.right==null&&rootR.left==null&&rootR.right!=null&&rootL.left!=null){
                if (rootR.right.val==rootL.left.val)
                    return isSymmetric(rootL.left,rootR.right);
                else
                    return false;
            }
            //L左和R右不为空,L右R左为空
            else if(rootR.right==null&&rootL.left==null&&rootL.right!=null&&rootR.left!=null){
                if (rootL.right.val==rootR.left.val)
                    return isSymmetric(rootL.right,rootR.left);
                else
                    return false;
            }
            //都不为空
            else if (rootL.right!=null&&rootL.left!=null&&rootR.right!=null&&rootR.left!=null){
                if (rootL.right.val==rootR.left.val&&rootR.right.val==rootL.left.val)
                    return isSymmetric(rootL.right,rootR.left)&&isSymmetric(rootL.left,rootR.right);
                else
                    return false;
            }
            //为空的地方不对称,直接返回false
            else {
                return false;
            }
        }
}

通过之后我们看一看答案里的迭代算法。

看到了人家的递归算法短短十几行,效果和我的一样甚至更好,编码能力还有待提高。

好像没有符合上面考虑的三个要素,主要的思路就是按预定的顺序将树转变为一个链表,然后每次取出两个比较他们的值,他们在树中是对称的位置,所以这样可以实现。

迭代的过程是将树变为链表的这个阶段,后面是遍历的过程。

而迭代的过程又使用了递归的方法,所以实际上还是在递归啊。

你可能感兴趣的:(每日一题算法)