递归和分治

递归

递归(英语:Recursion),在计算机科学中,递归指的是一个函数在其定义中调用自身的方法。这种技术允许程序解决复杂问题,通过将它们分解为更小、更易管理的相似问题。递归通常与分治策略相关联,后者涉及将一个大问题分解为若干个小问题,单独解决这些小问题,然后将结果合并以得到最终解。

递归函数通常具有以下两个主要特征:

  1. 基本情况(Base Case):这是递归停止的条件。在达到基本情况时,函数将停止调用自身。例如,在计算阶乘的递归函数中,0!1! 通常作为基本情况。
  2. 递归步骤(Recursive Step):在这一步中,函数调用自身来解决子问题。这些子问题是原始问题的更小版本。

在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:
(1) 每次只能移动一个盘子;
(2) 盘子只能从柱子顶端滑出移到下一根柱子;
(3) 盘子只能叠在比它大的盘子上。

请编写程序,用栈将所有盘子从第一根柱子移到最后一根柱子。

你需要原地修改栈。

示例1:

 输入:A = [2, 1, 0], B = [], C = []
 输出:C = [2, 1, 0]

示例2:

 输入:A = [1, 0], B = [], C = []
 输出:C = [1, 0]

提示:

  1. A中盘子的数目不大于14个。

思路:

先分析简单情况:

一.n=1 时:直接将这个盘子从A拿出,放到C。

二.n=2 时:假设上面的盘子是甲,下面的盘子是乙。

甲:A->B 乙:A->C 甲:B->C

三.n时 :可以把上面n-1个盘子看出一个整体(一个盘子)甲,下面的第n个盘子是乙。

甲:A->B 乙:A->C 甲:B->C

此时:甲:A->B 这个就是一个小问题,把n-1个盘子从A移动到B,可以用C当媒介—递归

​ 甲:B->C 这个也是一个小问题,把n-1个盘子从B移动到C,可以用A当媒介—递归

#include <iostream>
#include <vector>
using namespace std;

void move(int n, vector<int>& source, vector<int>& target, vector<int>& auxiliary) {
    if (n == 1) {
        // 直接移动
        target.push_back(source.back());
        source.pop_back();
    } else {
        // 移动上面的 n-1 个盘子从 source 到 auxiliary
        move(n - 1, source, auxiliary, target);

        // 移动底下的盘子从 source 到 target
        target.push_back(source.back());
        source.pop_back();

        // 移动 n-1 个盘子从 auxiliary 到 target
        move(n - 1, auxiliary, target, source);
    }
}

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

int main() {
    vector<int> A = {3, 2, 1, 0}; // Tower A
    vector<int> B; // Tower B
    vector<int> C; // Tower C

    hanota(A, B, C);

    // Output the result
    cout << "Tower C after moving disks: ";
    for (int disk : C) {
        cout << disk << " ";
    }
    cout << endl;

    return 0;
}

分治算法 (Divide and Conquer)

分治算法是一种特殊类型的递归算法,具体包括以下三个步骤:

  1. 分解(Divide):将原问题分解成一系列子问题。这些子问题是原问题的较小版本,但与原问题具有相同的形式。
  2. 解决(Conquer):递归地解决这些子问题。如果子问题足够小,可以直接求解。
  3. 合并(Combine):将子问题的解合并起来,形成原问题的解。

分治算法的经典例子包括快速排序、归并排序、二分搜索等。在这些算法中,问题被分解成更小的部分,独立解决这些小问题,然后将解合并以解决原始问题。

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

**进阶:**如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。

#include <iostream>
#include <vector>
#include <climits>
using namespace std;

class Solution {
public:
    int maxSub(vector<int>& nums, int l, int r){
        if(l == r){
            return nums[l];
        }

        // 递归体——分治求解
        int mid = (l + r) / 2;

        // 左边最大子序和
        int lmax = maxSub(nums, l, mid);
        // 右边最大子序和
        int rmax = maxSub(nums, mid + 1, r);

        // 跨越中点的最大子序和
        int mmax =  mid_sum(nums, l, r, mid);

        // 返回三者中的最大值
        return max(max(lmax, rmax), mmax);
    }

    int mid_sum(vector<int>& nums, int l, int r, int mid){
        // 从中点向左扩展
        int lmax = INT_MIN; // 左边最大值
        int sum = 0; // 当前和
        for(int i = mid; i >= l; i--){
            sum += nums[i];
            lmax = max(lmax, sum);
        }

        // 从中点向右扩展
        int rmax = INT_MIN; // 右边最大值
        sum = 0; // 当前和
        for(int i = mid + 1; i <= r; i++){
            sum += nums[i];
            rmax = max(rmax, sum);
        }

        // 返回左右最大值之和
        return lmax + rmax;
    }

    int maxSubArray(vector<int>& nums) {
        int n = nums.size();
        int ans = INT_MIN;
        ans = maxSub(nums,0, n - 1);
        return ans;
    }
};

int main(){
    Solution s;
    vector<int> nums = {-2,1,-3,4,-1,2,1,-5,4};
    cout << s.maxSubArray(nums) << endl;
    return 0;
}

image.png

思路:

1.暴力:枚举起点和终点,计算区间内的和,取最大值。时间复杂度:O(n^2)

2.分治:时间复杂度:O(nlogn)

取中心点m=(l+r)/2。 和最大的区间要么出现在中心点左边,要么出现在中心点右边,要么横跨中心点。所以问题分解为求这三部分的最大区间和,然后取最大值。----分成3个独立的小问题,分治。

(1) 中心点左边的最大区间和:和原问题相同,递归。

(2) 中心点右边的最大区间和:和原问题相同,递归。

(3)横跨中心点的最大区间和:贪心求解—从中心点往左右两边延申。

从中心点不断往左延申,同时记录最大值lmax

从中心点不断往右延申,同时记录最大值rmax

横跨中心点的最大区间和:lmax+rmax

3.动态规划:线性动态规划。时间复杂度 O(n)。

状态:dp[i]=x 以第i个元素结尾的和最大的区间,最大和是 x

初始状态:dp[0]=nums[0]

转移方程:dp[i]=max(dp[i-1]+nums[i],nums[i])

最终答案:max(dp[i])

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Idea 2023.2.5配置(插件、Maven等)

IDEA2023.2.5配置 一. 插件Alibaba Java Coding Guidelines plugin supportMaven HelperMyBatisXSonarLintTranslationVuesion Theme 二. 自定义创建live template&#xff0c;快速写代码三. 修改全局配置3.1 Maven配置3.1.1 安装MavenStep1. 下载Step2. 安装Step3. 创建系统环…

论文阅读:“iOrthoPredictor: Model-guided Deep Prediction of Teeth Alignment“

文章目录 IntroductionMethodologyProblem FormulationConditional Geometry GenerationTSynNetAligned Teeth Silhouette Maps Generation ResultsReferences Github 项目地址&#xff1a;https://github.com/Lingchen-chen/iOrthopredictor Introduction 这篇文章提出了一种…

栈和队列

目录 1.栈 1.1栈的概念及结构 1.2栈的实现 2.队列 2.1队列的概念及结构 2.2队列的实现 1.栈 1.1栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈…

重视日常消防巡检有必要,智能巡检系统来帮忙

近日,山西吕梁市永聚煤矿一办公楼发生火灾&#xff0c;造成重大人员伤亡&#xff0c;事故造成26人死亡、38人受伤。 是的&#xff0c;你没看错&#xff0c;煤矿公司、办公楼火灾、重大伤亡。第一反应&#xff0c;煤矿即使出事故也多为作业事故&#xff0c;居然还能在日常消防安…

“Python+”集成技术高光谱遥感数据处理

高光谱遥感数据处理的基础、python开发基础、机器学习和应用实践。重点解释高光谱数据处理所涉及的基本概念和理论&#xff0c;旨在帮助学员深入理解科学原理。结合Python编程工具&#xff0c;专注于解决高光谱数据读取、数据预处理、高光谱数据机器学习等技术难题&#xff0c;…

Chrome中设置安全来源域名

目的&#xff1a; 使得本地映射的域名能被浏览器安全访问&#xff0c;允许调用设备资源 步骤&#xff1a; 在Chrome中导航栏打开 chrome://flags/#unsafely-treat-insecure-origin-as-secure 填入hosts域名&#xff1a;如 http://h5-twzc003.local.com 参考&#xff1a; h…

AutoSAR CANIF层配置代码分析

CAN物理控制单元 配置&#xff1a; 生成的代码&#xff1a; CanIf_CtrlStates 解析 类型&#xff1a; typedef union CanIf_CtrlStatesUTag {CanIf_CtrlStatesType raw[3];CanIf_CtrlStatesStructSType str; }CanIf_CtrlStatesUType;typedef struct sCanIf_CtrlStatesType {C…

自定义歌曲试听SeekBar

看到这个效果&#xff0c;可能会想到完全自定义一个控件&#xff0c;其实我们在系统Seekbar的基础上&#xff0c;将progressDrawable中progress背景设为透明后&#xff0c;叠加绘制试听状态下的进度区域即可 class PlayerSeekBar JvmOverloads constructor(context: Context,a…

客服中心的客户关系管理核心功能

根据国外的调查&#xff0c;拥有客服中心的运营机构&#xff0c;可以保持85%左右的客户忠诚度&#xff0c;而接受过专业培训的客户中心可以将客户忠诚度提高到99%。客服中心作为客户关系管理的前沿&#xff0c;通过提供服务、实时沟通、搜集与分析客户信息、预测客户需求来提升…

SQL常见函数整理 —— lead()向下偏移

1. 用法 是在窗口函数中使用的函数&#xff0c;它用于获取当前行的下一行&#xff08;后一行&#xff09;的某个列的值。具体来说&#xff0c;LEAD() 函数可用于查找任何给定行的下一行&#xff08;后一行&#xff09;的值&#xff0c;同时也可控制行数偏移量&#xff08;offse…

每日汇评:澳元多头着眼于50%的斐波那契水平

澳元兑美元跳涨至三个月高点上方&#xff0c;并从多种因素中获得支撑&#xff1b; 对美联储已经结束加息的预期继续严重打压美元&#xff1b; 对中国出台更多刺激措施的乐观情绪和积极的风险基调也有利于澳元&#xff1b; 澳元兑美元周一连续获得强劲的后续积极牵引力&#xff…

在列表控件上显示提示信息

当我们在实现列表控件上的提示信息的时候&#xff0c;我们需要处理的一个难点是处理列表条目的折叠和展开这两种情况。 所谓列表条目的折叠&#xff0c;即在大图标模式(Large Icon Mode)下&#xff0c;列表条目的文字过长而被截断的情况。当用户选择这个条目后&#xff0c;条目…

损失函数总结(十五):MSLELoss、RMSLELoss

损失函数总结&#xff08;十五&#xff09;&#xff1a;MSLELoss、RMSLELoss 1 引言2 损失函数2.1 MSLELoss2.2 RMSLELoss 3 总结 1 引言 在前面的文章中已经介绍了介绍了一系列损失函数 (L1Loss、MSELoss、BCELoss、CrossEntropyLoss、NLLLoss、CTCLoss、PoissonNLLLoss、Gau…

城市生命线丨市政综合管廊监测系统的效果

市政综合管廊&#xff0c;又被称为城市生命线&#xff0c;是我们在地下建造的一个智慧而高效的空间。它把市政、电力、通讯、燃气、给排水等各种管线集于一体&#xff0c;解决了城市中反复开挖路面、架空线网密集、管线事故频发等问题&#xff0c;为城市运行提供了重要的基础设…

C#,怎么修改(VS)Visual Studio 2022支持的C#版本

一些文字来自于 Microsoft . &#xff08;只需要读下面的红色文字即可&#xff01;&#xff09; 1 C# 语言版本控制 最新的 C# 编译器根据项目的一个或多个目标框架确定默认语言版本。 Visual Studio 不提供用于更改值的 UI&#xff0c;但可以通过编辑 .csproj 文件来更改值。…

浅谈餐饮业油烟污染现状及在线监测系统的设计与应用

贾丽丽 安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;城市餐饮业油烟污染成了困扰城区环境保护部门和人民群众日常生活的主要问题。油烟污染已经成为我国一个重大的污染源&#xff0c;是形成PM2.5的重要污染源之一&#xff0c;为了解决餐饮业油烟管理方面存在的问…

linux镜像的下载,系统下载(个人使用)

文章目录 一、系统之家二、国内镜像源三、Centos官网四、安装成功截图五、镜像类型的区别参考文档 一、系统之家 系统之家官网 二、国内镜像源 下载镜像地址&#xff1a; 1、官网地址&#xff1a;https://www.centos.org/ 2、阿里镜像站&#xff1a;https://mirrors.aliyu…

人工智能基础_机器学习041_Sigmoid函数详解_Sigmoid损失函数推导_最大似然函数推导---人工智能工作笔记0081

然后我们再来看一下sigmoid函数的推导过程,可以看到首先我们把 sigmoid的函数写成两种情况 可以看到P(y|x;theta) = htheta(x), y=1 这个时候y=1 也就是是一种分类,然后另一种,就是相减, 是1-htheta(x) 可以看到,把两个公式河道一起就得到了下面的概率公式. 这里是有关概率…

被OpenAI开除后,创始人奥特曼在微软找到了新工作

微软首席执行官纳德拉宣布&#xff0c;OpenAI创始人Sam Altman和Brockman及其同事将加入微软。随后&#xff0c;Altman转发了他的推特。 此前&#xff0c;外媒消息称&#xff0c;OpenAI首席科学家伊尔亚苏茨克维&#xff08;Ilya Sutskever&#xff09;周日晚告知公司员工&…

Dubbo快速实践

文章目录 架构相关概念集群和分布式架构演进 Dubbo概述Dubbo快速入门前置准备配置服务接口配置Provider配置Consumer Dubbo基本使用总结 本文参考https://www.bilibili.com/video/BV1VE411q7dX 架构相关概念 集群和分布式 集群&#xff1a;很多“人”一起 &#xff0c;干一样…