LeetCode每日一题(题1028)

前言

最近在刷LeetCode每日一题,每次做完之后总能有些收获,所以想着不如每天写个博客记录一下做的题目的解法以及自己写的时候问题出在哪里。

题目

从先序遍历还原二叉树

题目大意:
给出一个字符串"1-2–3--4-5–6--7",1代表节点的值,前面的-个数代表节点的深度。如果只有一个子节点,保证这个节点为左子节点。
返回一个二叉树。

思路

一看到树的题目,首先就想到了使用递归。
这道题显然是不断递归生成子节点,那首先需要把一些值设置为全局变量。
需要设置为全局变量的值有

  • index :当前字符位。
  • chars :字符数组。

然后对于一次递归来说,首先要获得当前节点的值。
这边需要注意当前节点的值可能不止一位,那么需要判断当前位置的值是否为数字,如果是的话则保存下来并且将index++,然后最后获得一个整数,同时要注意index不要越界了。

接下来判断后面有多少个’-’,如果个数为当前deep+1,那说明是左子树,进行递归。
如果不是,那么说明是当前节点的兄弟节点,或者父节点的兄弟,总之说明该节点没有子树了,就需要返回。
对于右子树来说也是同样的操作。
这里要注意index的值,不要越界了,一旦判断index >= length就说明这是最后一个节点,直接返回该节点。

代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    int index = 0;
    char[] chars;
    public TreeNode recoverFromPreorder(String S) {
        if(S == null || S.length() == 0)
            return null;
        index = 0;
        chars = S.toCharArray();
        return pre(1);
    }
    public TreeNode pre(int deep){
        if(index >= chars.length)
            return null;
        int val = 0;
        while(index < chars.length && chars[index] != '-'){
            val *= 10;
            val += chars[index]-'0';
            index++;
        }
        TreeNode node = new TreeNode(val);
        for(int i=0;i<deep;i++){
            if(index >= chars.length || chars[index+i] != '-')
                return node;
        }
        index += deep;
        node.left = pre(deep+1);
        for(int i=0;i<deep;i++){
            if(index >= chars.length || chars[index+i] != '-')
                return node;
        }
        index += deep;
        node.right = pre(deep+1);
        return node;
    }
}

错误

这次代码中主要犯了如下错误:
void类型的方法中修改对象,我写了如下代码:

public void mian(){
	TreeNode root = new TreeNode(1);
   getLeft(root.left);
}
public void getLeft(TreeNode node){
   node = new TreeNode(0);
}

在这个代码我想实现生成一个新的TreeNode并且赋值给root的左子树。但是这样并不能成功,root左子树还是null
这是因为当我将root.left传递给子方法的时候,子方法生成了一个局部变量node,并且将node的地址设置为root.left的地址也就是null。
当我执行node = new TreeNode(0);的时候我把node的地址又修改为了新生成的节点的地址TreeNode@4141d797(这是我在idea中输出的地址,实际不一定是这个)。
但是这个时候node.left依然还是null没有得到修改,所以方法返回之后什么也没有发生。
正确的代码写法应该如下:

 public void mian(){
 	TreeNode root = new TreeNode(1);
 	//这样就是将root.left的地址修改为node的地址,所以不会出错。
	root.left = getLeft();
 }
public TreeNode getLeft(){
	node = new TreeNode(0);
	return node;
}

后记

这次错误的原理其实早就在书上看到过了,但是实际写的时候还是犯了,果然是“纸上得来终觉浅,绝知此事要躬行”。
看了半天感觉没什么问题,一调试就发现了问题所在,感觉非常睿智。
总之,今天的题得到了如下收获:

  1. 想递归生成一个新的对象,老老实实返回,不要用void方法然后在里面生成。
  2. 看到字符串整数的时候,一定注意整数长度可能不止一位,leetcode的题老是只给你一位整数误导你,其实测试用例里有好多多位整数,这个时候需要先获得整个整数的位数然后再处理。
  3. 判断index是否越界。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值