【算法】递归、搜索与回溯算法

news2024/11/23 0:45:32

文章目录

  • 一. 名词解释
    • 1. 递归
      • 1.1 什么是递归?
      • 1.2 为什么会用到递归?
      • 1.3 如何理解递归?
      • 1.4 如何写好一个递归?
    • 2. 遍历和搜索
    • 3. 回溯和剪枝
  • 二. 递归系列专题
    • 1. 汉诺塔问题
    • 2. 合并两个有序链表
    • 3. 反转链表
    • 4. 两两交换链表中的节点
    • 5. pow(x, n) - 快速幂

一. 名词解释

1. 递归

1.1 什么是递归?

递归就是函数自己调用自己

1.2 为什么会用到递归?

本质:我们在解决主问题时,会遇到和主问题相同的子问题,而子问题和主问题的解决方式一样,所以必定会出现函数自己调用自己(即递归)的情况。
在这里插入图片描述

递归示例一:二叉树前序遍历
在这里插入图片描述

递归示例二:快速排序
在这里插入图片描述

递归示例三:归并排序
在这里插入图片描述

1.3 如何理解递归?

实际处理递归问题时,如果能够宏观地看待递归,那么代码就会特别好写。其实做多了一些二叉树类的递归题目后,我们大抵就能够宏观地看待和理解递归了,可以总结出以下三个方面:

  • 不要在意递归的细节展开图,这会让你做题目时非常痛苦
  • 把递归的函数当成一个黑盒,我们只用传入参数,然后等待它返回给我们结果
  • 相信这个黑盒一定能完成任务

举例:二叉树的后序遍历
在这里插入图片描述

1.4 如何写好一个递归?

  1. 先找到相同的子问题(可以帮助我们完成函数头的设计)
  2. 只关心某一个子问题是如何解决的(有助于我们完成函数体的书写)
  3. 注意一下递归函数的出口(考虑哪些情况下,递归不能再进行下去)

2. 遍历和搜索

在这里插入图片描述

3. 回溯和剪枝

下面我们通过一个走迷宫的例子来解释回溯和剪枝:
在这里插入图片描述

我们在看题解的时候,经常看到有些人用深搜,有些人用广搜,还有些人用回溯;其实回溯就是深度优先搜索。

二. 递归系列专题


1. 汉诺塔问题


题目链接

算法原理

在这里插入图片描述

代码编写

class Solution 
{
private:
    void dfs(vector<int>& A, vector<int>& B, vector<int>& C, int n) 
    {
        // 0、递归出口:只剩一个盘子的话就直接移动
        if(n == 1) 
        {
            C.push_back(A.back());
            A.pop_back();
            return;
        }
        // 1. 先把 a 柱上 n - 1 个盘子借助 c 移动到 b 柱
        dfs(A, C, B, n - 1);
        // 2. 再把 a 柱剩下的一个盘子直接移动到 c 柱
        C.push_back(A.back());
        A.pop_back();
        // 3. 最后再把 b 柱上的 n - 1 个盘子借助 a 移动到 c 柱
        dfs(B, A, C, n - 1);
    }

public:
    void hanota(vector<int>& A, vector<int>& B, vector<int>& C) 
    {
        dfs(A, B, C, A.size());
    }
};

2. 合并两个有序链表


题目链接

算法原理
在这里插入图片描述

代码编写

class Solution 
{
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) 
    {
        // 0、特殊情况处理
        if(!list1) return list2;
        if(!list2) return list1;
        // 1、比较第一个节点值的大小
        // 2、记录较小节点,继续合并后续链表
        // 3、返回合并后链表的头节点
        if(list1->val < list2->val) 
        {
            list1->next = mergeTwoLists(list1->next, list2);
            return list1;
        }
        else
        {
            list2->next = mergeTwoLists(list1, list2->next);
            return list2;
        }
    }
};

3. 反转链表


题目链接

算法原理
在这里插入图片描述

代码编写

class Solution 
{
public:
    ListNode* reverseList(ListNode* head) 
    {
        // 0、特殊情况处理
        if(!head || !head->next) return head;
        // 1、先逆置后面的链表
        ListNode* ans = reverseList(head->next);
        // 2、让当前节点添加到逆置后的链表
        head->next->next = head;
        head->next = nullptr;
        // 3、返回值
        return ans;
    }
};

4. 两两交换链表中的节点


题目链接

算法原理
在这里插入图片描述

代码编写

class Solution 
{
public:
    ListNode* swapPairs(ListNode* head) 
    {
        // 0、特殊情况处理
        if(!head || !head->next) return head;
        // 1、先处理后部分链表两两交换
        auto tmp = swapPairs(head->next->next);
        // 2、对当前两个节点两两交换
        auto ans = head->next;
        head->next->next = head;
        head->next = tmp;
        // 3、返回值
        return ans;
    }
};

5. pow(x, n) - 快速幂


题目链接

算法原理
在这里插入图片描述

代码编写

class Solution 
{
private:
    double Pow(double x, long long n) 
    {
        if(!n) return 1;
        double tmp = Pow(x, n/2);
        return n % 2 == 1 ? tmp * tmp * x : tmp * tmp;
    }

public:
    double myPow(double x, int n) 
    {
        return n < 0 ? 1.0 / Pow(x, (long long)n * -1.0) : Pow(x, n);
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1305099.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

进程(IPC)_D3(2023-12-12)

XMind&#xff08;分图版&#xff09;

通过例子了解Go测试---来自Russ Cox的演讲

大家好. 几周前,我在澳大利亚 GopherCon 上发表了这个演讲[1], 但一些音/视频问题影响了效果,所以我在家重新录制了这个版本,enjoy&#xff01; 这次演讲的主题是编写好的测试&#xff0c;但首先让我们思考一下为什么需要编写测试。为什么程序员要编写测试呢&#xff1f;编程相…

java实现局域网内视频投屏播放(三)投屏原理

常见投屏方案 常见的投屏方案主要有以下几种&#xff1a; DLNA DLNA的全称是DIGITAL LIVING NETWORK ALLIANCE(数字生活网络联盟)。DLNA委员会已经于2017年1月5日正式解散&#xff0c;原因是旧的标准已经无法满足新设备的发展趋势&#xff0c;DLNA标准将来也不会再更新。但是…

主机访问Android模拟器网络服务方法

0x00 背景 因为公司的一个手机app的开发需求&#xff0c;要尝试链接手机开启的web服务。于是在Android Studio的Android模拟器上尝试连接&#xff0c;发现谷歌给模拟器做了网络限制&#xff0c;不能直接连接。当然这个限制似乎从很久以前就存在了。一直没有注意到。 0x01 And…

鸿蒙系统最近删除文件夹的路径

鸿蒙手机上删除文件&#xff0c;会将文件移动到类似回收站的路径下&#xff0c;如何找到这个路径&#xff1f; 先找用文件管理器找到一个文件 比如aaa.jpg &#xff0c;这时在调试的shell下面运行 find . -name aaaa.jpg 得到如下 这时再删除该文件 再次运行 find . -name a…

小白如何启用和使用ChatGPT4插件的详细步骤演示

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

野牛物联网-OneNET配置教程

1、 本文愿景 OneNET物联网开放平台是中国移动打造的面向产业互联和智慧生活应用的物联网PaaS平台&#xff0c;也是市面上主流物联网云平台之一&#xff0c;野牛物联网为了便利大家&#xff0c;在此编写了配置接入该平台完整的一个流程。 2、 OneNET平台注册和配置 2.1、 注…

STL 源码剖析

临时对象的产生与运用 #include <stdio.h> #include<stdlib.h> #include<iostream> #include<vector> #include<algorithm> using namespace std;template <typename T> class print { public:void operator()(const T& elem){cout &…

ubuntu 20.04.6 server 服务器 下载与安装(配置静态IP)

下载地址&#xff1a;https://releases.ubuntu.com/20.04.6/ubuntu-20.04.6-live-server-amd64.iso 第一步&#xff1a; 准备U盘&#xff0c;使用软碟通将下载好的镜像写入到U盘中 软碟通网址&#xff1a;https://www.cn.ultraiso.net/xiazai.html 点击&#xff1a;文件 ->…

交换机配置本地端口镜像示例(1:1)

镜像概念 定义 镜像是指将指定源的报文复制一份到目的端口。指定源被称为镜像源&#xff0c;目的端口被称为观察端口&#xff0c;复制的报文被称为镜像报文。 镜像可以在不影响设备对原始报文正常处理的情况下&#xff0c;将其复制一份&#xff0c;并通过观察端口发送给监控…

【LeetCode-树】-- 109.有序链表转换二叉搜索树

109.有序链表转换二叉搜索树 方法&#xff1a;找到链表的中点&#xff0c;将其作为根节点 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNo…

SpringBoot集成系列--Kakfa

文章目录 一、代码1、添加依赖2、配置kafka3、创建生产者4、创建消费者5、测试 二、遇到问题1、could not be established. Broker may not be available2、Error while fetching metadata with correlation id xxx 一、代码 1、添加依赖 在pom.xml文件中添加Kafka的依赖 &l…

NFC物联网解决方案应用实例:基于NFC的通用物流链防伪溯源

NFC物联网系统解决方案已在某局进行推广应用&#xff0c;给出了某省内出口蔬菜水果检验检疫监管的物联网解决方案。 依据相关法规&#xff0c;出口蔬菜必须在质检总局注册种植基地进行种植&#xff0c;出口前按批次向产地检验检疫部门进行申报&#xff0c;按时在集中监管区统一…

Leetcode—2961.双模幂运算【中等】

2023每日刷题&#xff08;五十六&#xff09; Leetcode—2961.双模幂运算 实现代码 class Solution { public:int func(int a, int b) {int ans 1;for(int i 0; i < b; i) {ans * a;ans % 10;}return ans;}int func2(int a, int b, int m) {int ans 1;for(int i 0; i …

通过pull request执行结果运行自动化测试脚本

前提条件 已安装 Jenkins&#xff0c;并且安装插件Generic Webhook Trigger Plugin 配置 Jenkins创建一个 pipeline项目如图所示在Jenkins任务的build triggers中勾选Generic Webhook Trigger, 并且填写token在代码仓库管理平台&#xff08;截图的是bitbucket)&#xff0c;配…

Python之Requests库使用总结

概述 Requests是python中一个很Pythonic的HTTP库&#xff0c;用于构建HTTP请求与解析响应 Requests开发哲学 Beautiful is better than ugly.(美丽优于丑陋) Explicit is better than implicit.(直白优于含蓄) Simple is better than complex.(简单优于复杂) Complex is bett…

充电宝详解及推荐

一、充电宝选购攻略 二、充电宝的分类 &#xff08;1&#xff09;常规充电宝&#xff08;慢充&#xff09; 就是输出电压5V &#xff0c;输出电流1A或者2A的这种。 按照功率计算公示&#xff1a;PU*I&#xff0c; 这种充电宝给手机充电最快也就是&#xff1a;5.1V2.1A10.71W…

SpringBoot+Netty+Websocket实现消息推送

这样一个需求&#xff1a;把设备异常的状态每10秒推送到页面并且以弹窗弹出来&#xff0c;这个时候用Websocket最为合适&#xff0c;今天主要是后端代码展示。 添加依赖 <dependency><groupId>io.netty</groupId><artifactId>netty-all</artifact…

springboot3.2.x支持虚拟线程

背景&#xff1a; 大家都知道jdk21已经发布一段时间了&#xff0c;springboot3.2开始正式支持虚拟线程了&#xff1b; 支持虚拟线程&#xff1a; 1、spring.threads.virtual.enabledtrue 开启虚拟线程 2、Servlet Web 服务器 当启用虚拟线程时&#xff0c;Tomcat和Jetty将使…

KubeSphere应用【二】Docker安装

一、Docker安装 1.下载Docker安装包 【地址】Index of linux/static/stable/x86_64/ 2.上传至服务器 # 解压文件 tar -xvf docker-20.10.10.tgz# 将docker 目录中的所有文件复制至/usr/bin/目录下 cp docker/* /usr/bin 3.配置docker.service文件 vim /usr/lib/systemd/sy…