leetcode513.找树左下角的值与leetcode17.电话号码的字母组合

本文探讨了回溯和递归在编程中的应用,通过电话号码和求左下角值的两个例子,解释了回溯的三步过程,包括确定返回值和参数、终止条件以及递归逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

回溯

回溯的本质是穷举,穷举所有可能,然后选出我们想要的答案。

关于回溯的理解和本质在之前已经讲过,今天做了几道题目,对于其中两道找左下角的值和电话号码的字母组合都用到了回溯。其实找左下角的值利用层序遍历更加简单和直观,但是为了增加对递归的理解,用递归做也是可以的。


回溯(递归)三步

  1. 确定返回值和参数

对于电话号码这道题,虽然是字符串,但是可以抽象成树形结构。

  首先需要一个字符串s来收集叶子节点的结果,然后用一个字符串数组res保存起来,这两个变量我依然定义为全局。

再来看参数,参数指定是有题目中给的string digits,然后还要有一个参数就是int型的index。

注意这个index可不是 77.组合 (opens new window)216.组合总和III (opens new window)中的startIndex了。

这个index是记录遍历第几个数字了,就是用来遍历digits的(题目中给出数字字符串),同时index也表示树的深度。

//设置全局列表存储最后的结果
    List<String> list = new ArrayList<>();

//比如digits如果为"23",num 为0,则str表示2对应的 abc
    public void backTracking(String digits, String[] numString, int num)

对于左下角的值,其实题目的本质就是求最大深度的最左边的值。当用DFS遍历时不会涉及对中间节点的处理逻辑。所以前中后序都是可以的。因为无论前中后序,都是先遍历左再遍历右(节点)。其最大深度用Deep作为全局变量,值用value记录。参数为根节点和每次遍历的深度。

private int Deep = -1;
private int value = 0;
private void findLeftValue (TreeNode root,int deep) 

2、回溯(递归)终止条件

对于电话号码这道题目,当记录的num长度和传入的字符串长度相同时,递归结束。

此时,需要进行记录路径字符数组。

//遍历全部一次记录一次得到的字符串
        if (num == digits.length()) {
            list.add(temp.toString());
            return;
        }

左下角的值则可以理解为到叶子节点则递归终止。

if (root == null) return;
        if (root.left == null && root.right == null) {
            if (deep > Deep) {
                value = root.val;
                Deep = deep;
            }
        }

3、递归&回溯逻辑

对于电话号码的这道题。不像二叉树这种天然的二分树,这道题需要自己拆分循环次数,因此在递归前应该先找到循环次数,对于这道题,循环次数就是当前数字对应的字母字符个数。进入循环后即需要添加当前的字符而后进入递归,递归需要弹出递归前加入的字符。目的:找到所有字符的组成。

String str = numString[digits.charAt(num) - '0'];
        for (int i = 0; i < str.length(); i++) {
            temp.append(str.charAt(i));
            //c
            backTracking(digits, numString, num + 1);
            //剔除末尾的继续尝试
            temp.deleteCharAt(temp.length() - 1);
        }

对于左下角值这个题目来说,每次递归都需要判断递归的下一节点是否为空来避免空指针异常。其次递归前需要将deep+1,递归结束后,需要弹出该深度。目的:遍历所有深度。

if (root == null) return;
        if (root.left == null && root.right == null) {
            if (deep > Deep) {
                value = root.val;
                Deep = deep;
            }
        }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值