算法妙妙屋-------2..回溯的奇妙律动

news2025/1/15 8:50:39

回溯算法是一种用于系统性地搜索和解决问题的算法,它以深度优先搜索(DFS)为基础,用来探索所有可能的解决方案。通过递归地尝试候选解并在必要时回退(即“回溯”),它能够高效地解决许多涉及组合、排列和分割问题的场景。

在这里插入图片描述

核心思想

  1. 递归:回溯算法通常以递归方式实现,每次深入问题的一个分支。
  2. 状态空间树:将问题抽象成一个树形结构,每个节点代表一个部分解或状态。
  3. 剪枝:在探索过程中,提前排除不可能的解以减少计算量。
  4. 回退:当某一条路径无法产生有效解时,返回上一步并尝试其他路径。

典型应用

  • 排列与组合问题:如求全排列、子集生成。
  • 路径搜索问题:如迷宫问题、数独求解。
  • 优化问题:如0/1背包问题。
  • 约束满足问题:如八皇后问题、图着色问题。

算法流程

  1. 选择:选择一个可能的路径或解分支。
  2. 约束检查:判断当前选择是否满足问题的约束条件。
  3. 递归搜索:继续深入探索下一个状态。
  4. 回溯:若当前选择无效,则返回上一步重新选择。

优势与不足

  • 优势:实现简单,适合解决所有可能解的穷举问题。
  • 不足:在问题规模较大时,计算复杂度可能过高,需要结合剪枝优化。

简单示例(伪代码):

def backtrack(path, options):
    if 满足结束条件:
        记录结果
        return
    for option in options:
        做选择
        backtrack(新的路径, 剩余选择)
        撤销选择

通过以上步骤,回溯算法能够在复杂解空间中寻找问题的最优解或所有可能解。

1.单词搜索

题目链接:单词搜索

在这里插入图片描述
解题思路:

  • 1.将整个数组向外扩充一环(避免讨论边缘问题
  • 2.进行深度优先搜索
class Solution {
public:

bool dfs(vector<vector<char>>& square, string word,int position,int i,int j,vector<vector<bool>>& check)
{
  if(position==word.size())
  return true;

  if(square[i][j+1]==word[position]&&!check[i][j+1])//判断右
  {
      check[i][j+1]=true;
      if(dfs(square, word,position+1,i,j+1,check))
      {
        return true;//这种类型的题目需要return,因为只需查找一个即可满足题意。
      }
      else
      {
        check[i][j+1]=false;
      }
  }
   
   if(square[i][j-1]==word[position]&&!check[i][j-1])//判断左
  {
      check[i][j-1]=true;
      if(dfs(square, word,position+1,i,j-1,check))
      {
        return true;
      }
      else
      {
        check[i][j-1]=false;
      }
  }

  if(square[i+1][j]==word[position]&&!check[i+1][j])//判断下
  {
      check[i+1][j]=true;
      if(dfs(square, word,position+1,i+1,j,check))
      {
        return true;
      }
      else
      {
        check[i+1][j]=false;
      }
  }


  if(square[i-1][j]==word[position]&&!check[i-1][j])//判断上
  {
      check[i-1][j]=true;
      if(dfs(square, word,position+1,i-1,j,check))
      {
        return true;
      }

      else
      {
        check[i-1][j]=false;
      }
  }
  return false;
}


    bool exist(vector<vector<char>>& board, string word) {
        int row=board.size();
        int line=board[0].size();
        vector<vector<bool>>check(row+2,vector<bool>(line+2,false));//初始化二维数组
        vector<vector<char>>square(row+2,vector<char>(line+2,'0'));

        for(int i=1;i<row+1;i++)
        {
           for(int j=1;j<line+1;j++)
           {
               square[i][j]=board[i-1][j-1];
           }
        }

        for(int i=1;i<row+1;i++)
        {
           for(int j=1;j<line+1;j++)
           {
               if(square[i][j]==word[0])
               {
                   check[i][j]=true;
                  if(dfs(square,word,1,i,j,check))
                  {
                    return true;
                  }
                   check[i][j]=false;  //恢复现场
               }
           }
        }
        return false;
    }
};

2.黄金矿工

题目链接:黄金矿工

在这里插入图片描述
解题思路:

  • 枚举矩阵中所有的位置当成起点,来⼀次深度优先遍历,统计出所有情况下能收集到的⻩⾦数的最⼤值即可。
class Solution {
public:

 
 int maximum=0;
 int sum=0;


    void dfs(vector<vector<int>>& square,int i,int j,vector<vector<bool>>& check)//不需要return,因为要全部遍历一遍才能找到最优解
    {
       if(square[i][j+1]!=0&&!check[i][j+1])//判断右
       {
        check[i][j+1]=true;
        sum+=square[i][j+1];
        dfs(square,i,j+1,check);
        check[i][j+1]=false;
        sum-=square[i][j+1];
       }

   
     if(square[i][j-1]!=0&&!check[i][j-1])//判断左
     {
      check[i][j-1]=true;
      sum+=square[i][j-1];
      dfs(square,i,j-1,check);
      check[i][j-1]=false;
      sum-=square[i][j-1];
     }
      
  

  if(square[i+1][j]!=0&&!check[i+1][j])//判断下
  {
      check[i+1][j]=true;
      sum+=square[i+1][j];
      dfs(square,i+1,j,check);
      check[i+1][j]=false;
      sum-=square[i+1][j];
      
  }


  if(square[i-1][j]!=0&&!check[i-1][j])//判断上
  {
      check[i-1][j]=true;
      sum+=square[i-1][j];
      dfs(square,i-1,j,check);
      check[i-1][j]=false;
      sum-=square[i-1][j];
      
  }

   
  maximum=max(sum,maximum);//每一次dfs走到底的时候就进行比较,保留最大值
     
}

    int getMaximumGold(vector<vector<int>>& grid) {
        int row=grid.size();
        int line=grid[0].size();
        vector<vector<bool>>check(row+2,vector<bool>(line+2,false));//初始化二维数组
        vector<vector<int>>square(row+2,vector<int>(line+2,0));
        
        for(int i=1;i<row+1;i++)
        {
           for(int j=1;j<line+1;j++)
           {
               square[i][j]=grid[i-1][j-1];
           }
        }

        for(int i=1;i<row+1;i++)
        {
           for(int j=1;j<line+1;j++)
           {
              if(square[i][j]!=0)
              {
                check[i][j]=true;
                sum+=square[i][j];
                dfs(square,i,j,check);
                check[i][j]=false;
                sum=0;//更换起点,路径长度要归零。
              }
           }
        }
      return maximum;
    }
};

注意:黄金矿工和单词搜索不一样,单词搜索只需要找到一个满足题意的路径即可(即找到之后剩下的无需遍历需要return 返回)而黄金矿工需要遍历所有路径来找到最优解,无需return

3.不同路径III

题目链接:不同路径III

在这里插入图片描述
解题思路:

  • 递归结束条件:当前位置的元素值为2,若此时可⾛的位置数量num的值为0,则cnt的值加⼀;
class Solution {
public:

int num=0;
int row=0;
int line=0;


bool judge(vector<vector<bool>>&check)
{
    for(int i=1;i<row+1;i++)
        {
           for(int j=1;j<line+1;j++)
           {  
               if(check[i][j]==false)//有格子没走过
               return false;
           }
        }
    return true;//所有格子都走过
}




void dfs(vector<vector<int>>& square,int i,int j,vector<vector<bool>>&check)
{
       if(square[i][j]==2)  //走到终点
       {
            if(judge(check))
            {
                num++;  //路径数量++;
            }
       }


       if((square[i][j+1]==0||square[i][j+1]==2)&&!check[i][j+1])//判断右
       {
          check[i][j+1]=true;
          dfs(square,i,j+1,check);
          check[i][j+1]=false;//恢复现场
       }

       if((square[i][j-1]==0||square[i][j-1]==2)&&!check[i][j-1])//判断左
       {
          check[i][j-1]=true;
          dfs(square,i,j-1,check);
          check[i][j-1]=false;//恢复现场
       }

       if((square[i+1][j]==0||square[i+1][j]==2)&&!check[i+1][j])//判断下
       {
          check[i+1][j]=true;
          dfs(square,i+1,j,check);
          check[i+1][j]=false;//恢复现场
       }



       if((square[i-1][j]==0||square[i-1][j]==2)&&!check[i-1][j])判断上
       {
          check[i-1][j]=true;
          dfs(square,i-1,j,check);
          check[i-1][j]=false;//恢复现场
       }

}


    int uniquePathsIII(vector<vector<int>>& grid) {
        row=grid.size();
        line=grid[0].size();
        int position_row=0;
        int position_line=0;
        vector<vector<bool>>check(row+2,vector<bool>(line+2,false));
        vector<vector<int>>square(row+2,vector<int>(line+2,3));

        for(int i=1;i<row+1;i++)
        {
           for(int j=1;j<line+1;j++)
           {
               square[i][j]=grid[i-1][j-1];
               if(square[i][j]==1||square[i][j]==-1)
               {
                    if(square[i][j]==1)
                    {
                        position_row=i;//找入口的行
                        position_line=j;//找入口的列
                    }
                    check[i][j]=true; //
               }
           }
        }
     

     dfs(square,position_row, position_line,check);
     return num;
    }
};

在这里插入图片描述

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

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

相关文章

如何在Jupyter中快速切换Anaconda里不同的虚拟环境

目录 介绍 操作步骤 1. 选择环境&#xff0c;安装内核 2. 注册内核 3. 完工。 视频教程 介绍 很多网友在使用Jupyter的时候会遇到各种各样的问题&#xff0c;其中一个比较麻烦的问题就是我在Anaconda有多个Python的环境里面&#xff0c;如何让jupyter快速切换不同的Pyt…

《自动驾驶与机器人中的SLAM技术》ch9:自动驾驶车辆的离线地图构建

目录 1 点云建图的流程 2 前端实现 2.1 前端流程 2.2 前端结果 3 后端位姿图优化与异常值剔除 3.1 两阶段优化流程 3.2 优化结果 ① 第一阶段优化结果 ② 第二阶段优化结果 4 回环检测 4.1 回环检测流程 ① 遍历第一阶段优化轨迹中的关键帧。 ② 并发计算候选回环对…

2025/1/12 复习JS

我乞求你别再虚度光阴 ▶ 空心 --------------------------------------------------------------------------------------------------------------------------------- 摘自哔哩哔哩听课笔记。 01 上篇&#xff1a;核心语法 1.基于页面效果的操作 <!DOCTYPE html>…

初学stm32 --- II2C_AT24C02,向EEPROM中读写数据

目录 IIC总线协议介绍 IIC总线结构图 IIC协议时序 1. ACK&#xff08;Acknowledge&#xff09; 2. NACK&#xff08;Not Acknowledge&#xff09; IO口模拟II2C协议 发送起始信号&#xff1a; 发送停止信号&#xff1a; 检测应答信号&#xff1a; 发送应答信号&#x…

Angular-生命周期及钩子函数

什么是生命周期 Angular 创建和渲染组件及其子组件&#xff0c;当它们绑定的属性发生变化时检查它们&#xff0c;并在从 DOM 中移除它之前销毁它们。生命周期函数通俗的讲就是组件创建、组件更新、组件销毁的时候会触发的一系列的方法。当 Angular 使用构造函数新建一个组件或…

vue(五)基础语法--循环遍历指令

目录 简单数据的处理&#xff08;常用&#xff09; 复杂数据&#xff08;json数据&#xff09; v-for 与对象 通过key管理状态 Key的来源 这一节类同于vue&#xff08;四&#xff09;基础语法--条件渲染-CSDN博客 &#xff0c;本质都是那些基础语句语法的实现。 简单介绍 …

【全套】基于分类算法的学业警示预测信息管理系统

【全套】基于分类算法的学业警示预测信息管理系统 【摘 要】 随着网络技术的发展基于分类算法的学业警示预测信息管理系统是一种新的管理方式&#xff0c;同时也是现代学业预测信息管理的基础&#xff0c;利用互联网的时代与实际情况相结合来改变过去传统的学业预测信息管理中…

解决线程安全问题,Lock锁,死锁以及如何避免,线程的通信和线程池

如何解决线程安全问题 当多个线程共享一个资源时&#xff0c;则可能出现线程安全问题。 java中解决线程安全的方式有三种 第一种: 同步代码块 第二种: 同步方法 第三种: Lock 同步代码块 synchronized(锁对象){ 需要同步的代码。 } synchronized 同步的意思 锁对象可以是任…

源码编译安装httpd 2.4,提供系统服务管理脚本并测试(两种方法实现)

方法一&#xff1a;使用 systemd 服务文件 sudo yum install gcc make autoconf apr-devel apr-util-devel pcre-devel 1.下载源码 wget https://archive.apache.org/dist/httpd/httpd-2.4.46.tar.gz 2.解压源码 tar -xzf httpd-2.4.46.tar.gz 如果没有安装tar 记得先安装…

基于微信小程序的智能停车场管理系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

LabVIEW驱动电机实现样品自动搜索

利用LabVIEW控制电机驱动相机在XY平面上进行扫描&#xff0c;以检测样品位置。样品最初可能位于相机视野范围之外&#xff0c;需要实现自动搜索样品位置并完成精确定位扫描的功能。该系统需具有以下特点&#xff1a; 高效搜索&#xff1a;能够快速确定样品位置&#xff0c;缩短…

excel 整理表格,分割一列变成多列数据

数据准备 对于很多系统页面的数据是没有办法下载的。 这里用表格数据来举例。随便做数据的准备。想要看excel部分的可以把这里跳过&#xff0c;从数据准备完成开始看。 需要一点前端基础知识&#xff0c;但不多&#xff08;不会也行&#xff09;。 把鼠标放在你想要拿到本地的…

MAC AndroidStudio模拟器无网络

先确认PC端是正常访问网络的&#xff1b; 模拟器端修改Wifi设置&#xff1a;设置 - 网络和互联网 - WALN设置 按照上图修改&#xff1b; IP设置&#xff1a;从DHCP修改为静态&#xff0c;IP地址&#xff1a;10.0.2.16 &#xff0c;网关&#xff1a;10.0.2.2 &#xff0c; DNS…

【Linux系统】Ext系列磁盘文件系统一

0. 从快递系统引入文件系统 理解文件系统&#xff1a;菜鸟驿站的类比 在日常生活中&#xff0c;我们常常会使用到快递服务来寄送和接收包裹。这个过程虽然看似简单&#xff0c;但背后却有着一套复杂而有序的管理系统在支撑。今天&#xff0c;我们将通过一个类比——将文件系统…

1Hive概览

1Hive概览 1hive简介2hive架构3hive与Hadoop的关系4hive与传统数据库对比5hive的数据存储 1hive简介 Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张数据库表&#xff0c;并提供类SQL查询功能。 其本质是将SQL转换为MapReduce/Spark的任务进…

Elasticsearch入门学习

Elasticsearch是什么 Elasticsearch 是一个基于 Apache Lucene 构建的分布式搜索和分析引擎、可扩展的数据存储和矢量数据库。 它针对生产规模工作负载的速度和相关性进行了优化。 使用 Elasticsearch 近乎实时地搜索、索引、存储和分析各种形状和大小的数据。 特点 分布式&a…

[读书日志]8051软核处理器设计实战(基于FPGA)第七篇:8051软核处理器的测试(verilog+C)

6. 8051软核处理器的验证和使用 为了充分测试8051的性能&#xff0c;我们需要测试每一条指令。在HELLO文件夹中存放了整个测试的C语言工程文件。主函数存放在指令被分为五大类&#xff0c;和上面一样。 打开后是这样的文件结构。HELLO.c是主文件&#xff0c;这是里面的代码&am…

【Vue实战】Vuex 和 Axios 拦截器设置全局 Loading

目录 1. 效果图 2. 思路分析 2.1 实现思路 2.2 可能存在的问题 2.2.1 并发请求管理 2.2.2 请求快速响应和缓存带来的问题 3. 代码实现 4. 总结 1. 效果图 如下图所示&#xff0c;当路由变化或发起请求时&#xff0c;出现 Loading 等待效果&#xff0c;此时页面不可见。…

一文读懂yolo11模型训练

一文读懂yolo11模型训练 一、环境准备 Anaconda安装 简介 Anaconda 是一个流行的开源 Python 发行版&#xff0c;专注于数据科学、机器学习、科学计算和分析等领域。它提供了一个强大的包管理器和环境管理器&#xff0c;名为 Conda&#xff0c;以及一个预装了大量科学计算和…

Apache PAIMON 学习

参考&#xff1a;Apache PAIMON&#xff1a;实时数据湖技术框架及其实践 数据湖不仅仅是一个存储不同类数据的技术手段&#xff0c;更是提高数据分析效率、支持数据驱动决策、加速AI发展的基础设施。 新一代实时数据湖技术&#xff0c;Apache PAIMON兼容Apache Flink、Spark等…