算法通过村第十八关-回溯|青铜笔记|什么叫回溯(后篇)


前言


提示:今夜思量千条路,明朝依旧卖豆腐。 --谚语

回溯是非常重要的算法思想之一,主要解决一些暴力枚举也搞不定的问题(这里埋个坑💣)例如组合、分割、子集、棋盘等等。从性能角度来看回溯算法的效率并不是很高,但是对于暴力也解决不了的问题,它往往很快可以出结果,效率低就可以理解了吧。接下来,就看看回溯的事情吧🤩

回溯热身问题

输出二叉树的所有路径:

参考题目地址:257. 二叉树的所有路径 - 力扣(LeetCode)

在这里插入图片描述

在这里插入图片描述

我们可以注意看这里有几个叶子节点,就有几条路径,那么怎么找叶子节点呢?我们知道深度优先搜索就是从根节点开始一直找到叶子结点,我们这里可以先判断当前节点是不是叶子节点,在决定是不是向下走,如果走到叶子节点,我们就加一条路径。

这里从回溯的角度看问题,达到第一条路径后,怎么得到第二条路径呢?当然很明显需要撤销一下上一个点对吧!我们继续看递归:

在这里插入图片描述
完整代码:(回溯操作)

 public List<String> binaryTreePaths(TreeNode root) {
        List<String> ans = new ArrayList<String>();
        dfs(root,new ArrayList(),ans);
        return ans; 
    }
    public static void dfs(TreeNode root, List<Integer> path,List<String> ans){
        if(root == null){
            return;
        }
        path.add(root.val);
        if(root.left == null && root.right == null){
            ans.add(getPathToString(path));
        }
        dfs(root.left,path,ans);
        dfs(root.right,path,ans);
        path.remove(path.size() - 1);
    }
    public static String getPathToString(List<Integer> path){
        StringBuilder sb = new StringBuilder();
        sb.append(path.get(0));
        for(int i = 1; i < path.size(); i++){
            sb.append("->").append(path.get(i));
        }
       return sb.toString();
    }
}

路径总和问题:

参考题目地址:113. 路径总和 II - 力扣(LeetCode)

在这里插入图片描述

在这里插入图片描述

本题需要怎么做呢?从上面的题目种,我们也有灵感,这里找的目标值是22,根节点的值是5,也就是说左右和为17.我们继续左子树,发现是4,此时我们要找的是13继续往下找左右子树。依次类推右边也是一样的。当然这里到达11时,我们就需要在往后找,目标值时2,显然这里7已经不合适了,移除7,继续访问2.

同样右边也是这样操作的,我们总和为17就完成目标了。

展示一下代码:(回溯操作)

    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<List<Integer>> res = new ArrayList<>();
        Deque<Integer> path = new ArrayDeque<>();
        dfs(root,targetSum,path,res);
        return res;
    }
    public void dfs(TreeNode root,int targetSum,Deque<Integer> path,List<List<Integer>> res ){
        if(root == null){
            return;
        }
        // 这里处理很关键
        targetSum -= root.val;
        path.add(root.val);
        // 添加一个条件
        if(targetSum ==0 && root.left == null && root.right == null){
            res.add(new LinkedList(path));
        }
        dfs(root.left,targetSum,path,res);
        dfs(root.right,targetSum,path,res);
        path.removeLast();

    }

总结

提示:回溯操作;撤回操作;递归和回溯;保留状态;回溯的核心问题


如果有帮助到你,请给题解点个赞和收藏,让更多的人看到 ~ ("▔□▔)/

如有不理解的地方,欢迎你在评论区给我留言,我都会逐一回复 ~

也欢迎你 关注我 ,喜欢交朋友,喜欢一起探讨问题。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我会尽力回答你的问题。 曲线积分和曲面积分都是数学中的重要概念,常用于物理、工程等领域的计算和分析。 首先,让我们来了解一下曲线积分。 曲线积分是沿着一条曲线对某个向量场进行积分的过程。具体来说,设曲线C为参数方程r(t)=(x(t), y(t), z(t)), t∈[a,b],向量场F为F=(P, Q, R),则曲线积分的形式为: ∫C F·dr = ∫ab F(r(t))·r'(t) dt 其中,·表示向量的点积,r'(t)表示曲线在t时刻的切向量。 接下来,让我们了解一下曲面积分。 曲面积分是沿着一个曲面对某个向量场进行积分的过程。具体来说,设曲面S为参数方程r(u,v)=(x(u,v), y(u,v), z(u,v)),向量场F为F=(P, Q, R),则曲面积分的形式为: ∫S F·dS = ∫∫S F(r(u,v))·n(u,v) dS 其中,·表示向量的点积,n(u,v)表示曲面在(u,v)处的法向量,dS表示曲面上面积元素。 在曲面积分中,常常会用到高斯公式和斯托克斯公式。 高斯公式是指对于任何一个有向光滑闭合曲面S和向量场F=(P,Q,R),都有: ∫S F·dS = ∫∫∫V div F dV 其中,div F表示向量场F的散度,V表示曲面S所围成的区域。 斯托克斯公式是指对于任何一个有向光滑曲面S和向量场F=(P,Q,R),都有: ∫S F·dr = ∫∫C curl F·n ds 其中,curl F表示向量场F的旋度,C表示曲面S的边界,n表示C的法向量,ds表示C上的弧长元素。 希望这些内容能够对你有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

师晓峰

啤酒饮料矿泉水,你的打赏冲一冲

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值