算法学习——LeetCode力扣回溯篇4

算法学习——LeetCode力扣回溯篇4

在这里插入图片描述

332. 重新安排行程

332. 重新安排行程 - 力扣(LeetCode)

描述

给你一份航线列表 tickets ,其中 tickets[i] = [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。

所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。

例如,行程 [“JFK”, “LGA”] 与 [“JFK”, “LGB”] 相比就更小,排序更靠前。
假定所有机票至少存在一种合理的行程。且所有的机票 必须都用一次 且 只能用一次。

示例

示例 1:

在这里插入图片描述

输入:tickets = [[“MUC”,“LHR”],[“JFK”,“MUC”],[“SFO”,“SJC”],[“LHR”,“SFO”]]
输出:[“JFK”,“MUC”,“LHR”,“SFO”,“SJC”]

示例 2:
在这里插入图片描述

输入:tickets = [[“JFK”,“SFO”],[“JFK”,“ATL”],[“SFO”,“ATL”],[“ATL”,“JFK”],[“ATL”,“SFO”]]
输出:[“JFK”,“ATL”,“JFK”,“SFO”,“ATL”,“SFO”]
解释:另一种有效的行程是 [“JFK”,“SFO”,“ATL”,“JFK”,“ATL”,“SFO”] ,但是它字典排序更大更靠后。

提示

  • 1 <= tickets.length <= 300
  • tickets[i].length == 2
  • fromi.length == 3
  • toi.length == 3
  • fromi 和 toi 由大写英文字母组成
  • fromi != toi

代码解析

回溯遍历(超时)

回溯遍历每一种可能
当出现第一种可能的路线,之间加入。
当出现新的可能路线,与老路线对比,如果字典排序小于,则替换老路线

class Solution {
public:
    vector<string> resul;
    vector<string> path;
    void backtraking(vector<vector<string>>& tickets , string Indnx ,  vector<bool> &used)
    {
    	//找到路线,看是否替换老的路径
    	//如果没有老路径直接加入,如果相同就返回,如果不同路径按照字典比较
        if(path.size()==tickets.size()+1)
        {
            if(resul.empty()==1) 
            {
                resul = path;
                return;
            }
            else if(resul == path) return;
            else 
            {
                for(int j=0 ;j<path.size();j++)
                {
                    for(int k=0 ;k<3;k++)
                    {
                        if(resul[j][k] == path[j][k]) continue;
                        else if(resul[j][k] < path[j][k])return;
                        else if(resul[j][k] > path[j][k]) 
                        {
                            resul.clear();
                            resul = path;
                            return;
                        }
                    }
                }
            }
            // cout<<"resu: ";
            // for(auto i:resul) cout<<i<<' ';
            // cout<<endl;
            return;
        }

        for(int i=0 ; i<tickets.size();i++)
        {
        	//如果当前机票使用过,或者当前机票目的地不对,跳过
            if(used[i]==true || tickets[i][0] != Indnx) continue;
            //如果当前机票可用,则加入路径
            if(used[i]== false && tickets[i][0] == Indnx)
            {
                used[i] = true;
                path.push_back(tickets[i][1]);
                //递归,确定递归找的新机票。下一站机票的开始机场,就是当前机票的目的地机场
                backtraking(tickets,tickets[i][1],used);
                used[i] = false;
                path.pop_back();
            }
        }
        return;
        
    }
    vector<string> findItinerary(vector<vector<string>>& tickets) {
        vector<bool> used(tickets.size(),false);
        path.push_back("JFK");
        backtraking(tickets,"JFK",used);
        return resul;
    }
};

排序再回溯

先对输入票排序,其中排序按照票的目的地的字典减少排序(因为出发点是确定的,目的地多种找最优解)
之后回溯遍历找路线,发现的第一个路线即为最优路线

class Solution {
public:
	//按飞机票目的地(字符串vector第二个参数)字典减小排序
     class compare
    {
    public:
        bool operator()( const vector<string> tickets1 ,const  vector<string> tickets2 )
        {
           
            if((tickets1[1])[0]  < (tickets2[1])[0]) return 1;
            else if((tickets1[1])[0]  == (tickets2[1])[0])
            {
                if((tickets1[1])[1]  < (tickets2[1])[1]) return 1;
                else if((tickets1[1])[1]  == (tickets2[1])[1])
                {
                    if((tickets1[1])[2]  < (tickets2[1])[2]) return 1;
                    else return 0;
                }
                 return 0;
            }
            return 0;
           
        }
    };
    vector<string> resul;
    vector<string> path;
    bool find = false;
    void backtraking(vector<vector<string>>& tickets , string Indnx ,  vector<bool> &used)
    {
    	//找到一个路径就不找了,直接是最优路径
        if(find == true ) return;
        if(path.size()==tickets.size()+1)
        {
                resul = path;
                find =true;
                return;
        }

        for(int i=0 ; i<tickets.size();i++)
        {
            if(used[i]==true || tickets[i][0] != Indnx) continue;
            if(used[i]== false && tickets[i][0] == Indnx)
            {
                used[i] = true;
                path.push_back(tickets[i][1]);
                backtraking(tickets,tickets[i][1],used);
                used[i] = false;
                path.pop_back();
            }
        }
        return;
        
    }
    vector<string> findItinerary(vector<vector<string>>& tickets) {
        vector<bool> used(tickets.size(),false);
        sort(tickets.begin(),tickets.end(),compare());
        // for(auto i:tickets) 
        // {
        //      cout<<'[';
        //     for(auto j:i)
        //     {
        //          cout<<j<<' ';
        //     }
        //      cout<<']';
        // }
           
        path.push_back("JFK");
        backtraking(tickets,"JFK",used);
        return resul;
    }
};

51. N 皇后

51. N 皇后 - 力扣(LeetCode)

描述

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。

示例

示例 1:
在这里插入图片描述

输入:n = 4
输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

示例 2:

输入:n = 1
输出:[[“Q”]]

提示

1 <= n <= 9

代码解析

递归遍历

主要是去除同行和同列

class Solution {
public:
    vector<vector<string>> result;
    vector<int>path;
    //求绝对值
    int abs(int a)
    {
        if (a < 0) return -a;
        else return a;
    }
    void backtraking(int n ,vector<bool> &used ,int deep)
    {	
    	//当深度大于n时返回
        if(deep > n) return;
        //当路径为最大深度,找到路径存入
        if(path.size() == n)
        {
        	//将数字路径转换成字符串路径
            vector<string> path_s;
            for(int i=0;i<n;i++)
            {
                string tmp ;
                for(int k=0;k<n;k++) tmp +='.';//建立n个.
                for(int j=0;j<n;j++)  if(j==path[i]) tmp[j] = 'Q';//在应该放Q的位置放Q
                path_s.push_back(tmp);//转换好的字符串存入路径
            }
            //存入结果
            result.push_back(path_s);
            return;
        }
		//层次循环,找到每一行的点。
        for(int i=0 ; i<n; i++)
        {
            if(used[i] == true) continue; //该点用过了,跳过。一个树枝的点只能用一次
            pair<int,int> x(deep,i);//当前可能有效点
            bool flag = true;
            //当前点,和path路径里面所有点依次对比
            for(int j =0 ; j < path.size() ;j++)
            {
                pair<int,int> y(j,path[j]);//path之前加入的点
                //检测当前点与之前路径点,是否在一列一行和对角线
                if( abs(x.first - y.first)==0 ||  abs(x.second - y.second)==0 
                    || abs(x.first - y.first) == abs(x.second - y.second) ) 
                    flag = false;
            }
            //检测是合格点,加入path
            if(flag == true)
            {
            	//记录该点使用
                used[i] = true;
                path.push_back(i);
                //递归,深度+1(找下一行)
                backtraking(n,used,deep+1);
                path.pop_back();
                used[i] = false;
            }
        }
        return;
    }
    vector<vector<string>> solveNQueens(int n) { 
        vector<bool> used(n,false);
        backtraking(n ,used,0);
        return result;
    }
};

37. 解数独

37. 解数独 - 力扣(LeetCode)

描述

编写一个程序,通过填充空格来解决数独问题。

数独的解法需 遵循如下规则:

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 ‘.’ 表示。

示例

示例 1:
在这里插入图片描述

输入:board = [[“5”,“3”,“.”,“.”,“7”,“.”,“.”,“.”,“.”],[“6”,“.”,“.”,“1”,“9”,“5”,“.”,“.”,“.”],[“.”,“9”,“8”,“.”,“.”,“.”,“.”,“6”,“.”],[“8”,“.”,“.”,“.”,“6”,“.”,“.”,“.”,“3”],[“4”,“.”,“.”,“8”,“.”,“3”,“.”,“.”,“1”],[“7”,“.”,“.”,“.”,“2”,“.”,“.”,“.”,“6”],[“.”,“6”,“.”,“.”,“.”,“.”,“2”,“8”,“.”],[“.”,“.”,“.”,“4”,“1”,“9”,“.”,“.”,“5”],[“.”,“.”,“.”,“.”,“8”,“.”,“.”,“7”,“9”]]
输出:[[“5”,“3”,“4”,“6”,“7”,“8”,“9”,“1”,“2”],[“6”,“7”,“2”,“1”,“9”,“5”,“3”,“4”,“8”],[“1”,“9”,“8”,“3”,“4”,“2”,“5”,“6”,“7”],[“8”,“5”,“9”,“7”,“6”,“1”,“4”,“2”,“3”],[“4”,“2”,“6”,“8”,“5”,“3”,“7”,“9”,“1”],[“7”,“1”,“3”,“9”,“2”,“4”,“8”,“5”,“6”],[“9”,“6”,“1”,“5”,“3”,“7”,“2”,“8”,“4”],[“2”,“8”,“7”,“4”,“1”,“9”,“6”,“3”,“5”],[“3”,“4”,“5”,“2”,“8”,“6”,“1”,“7”,“9”]]
解释:输入的数独如上图所示,唯一有效的解决方案如下所示:

在这里插入图片描述

提示

  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字或者 ‘.’
  • 题目数据 保证 输入数独仅有一个解

代码解析

class Solution {
public:
    bool cheack( vector<vector<char>>& board , int row ,int col ,int val)
    {
        for(int i=0 ; i< board[0].size() ;i++) //检查行
        {
            if(board[row][i] == val  )
            {
                return false;
            }
        }

        for(int i=0 ; i< board.size() ;i++) //检查列
        {
            if(board[i][col] == val)
            {
                return false;
            }
        }

        int startRow = (row / 3)*3;
        int startCol = (col / 3)*3;

        for(int i=startRow ; i < startRow + 3 ;i++) //检查小方块
        {
            for(int j=startCol ; j< startCol + 3 ;j++)
            {
                if(board[i][j] == val)
                {
                    return false;
                }
            }
        }
        return true;
    }
    bool backtarking(vector<vector<char>>& board)
    {
        for(int i=0 ; i< board.size() ; i++) //递归行
        {
            for(int j=0 ; j<board[0].size() ;j++)//递归列
            {
                if(board[i][j] != '.') continue;//已有的跳过
                for( char k = '1' ; k<='9';k++)
                {
                    if(cheack(board,i,j,k)) //检查当前k是否符合
                    {
                        board[i][j] = k;
                        if(backtarking(board)) return true; //当找到一组成功的,就不接着找了直接返回true
                        board[i][j] = '.';
                    }
                }
                return false ;
            }
        }
        return true;//行和列都满足了,返回找到
    }
    void solveSudoku(vector<vector<char>>& board) {
        bool tmp = backtarking(board);
    }
};

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

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

相关文章

Spring Boot 笔记 009 创建接口_更新用户基本信息

1.1.1 给User实体类添加校验 package com.geji.pojo;import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta…

一周学会Django5 Python Web开发-Django5 Hello World编写

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计14条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

SpringCloud之Eureka注册中心和负载均衡

SpringCloud之Eureka注册中心和负载均衡 微服务技术栈认识微服务单体架构分布式架构微服务 微服务拆分及远程调用微服务拆分注意事项 Eureka注册中心提供者与消费者原理分析服务调用出现的问题Eureka的作用 使用流程1、搭建EurekaServer2、注册user-service3、在order-service完…

【Godot4自学手册】第十三节初建创建敌人

从本节起&#xff0c;将要学习创建第一人。 一、创建敌人动画 1.导入素材。 在Sprites文件夹下新建Enemy文件夹&#xff0c;并将需要的敌人素材导入到文件夹。文档结构如下&#xff1a; 2.创建Enemy场景。 新建场景&#xff0c;根节点设置为CharacterBody2D&#xff0c;命…

Docker的常见命令以及命令别名

常见命令 命令说明docker pull拉取镜像docker push推送镜像到DockerRegistrydocker images查看本地镜像docker rmi删除本地镜像docker run创建并允许容器docker stop停止指定容器docker start启动指定容器docker restart重新启动容器docker rm删除指定容器docker ps查看容器do…

PR:熟悉PR工作环境

新建项目 设置自己的页面布局 首选项

vim编辑代码后退出编辑显示vim编辑的内容

在/etc/profile.d/下新建terminal.sh&#xff1a; 在terminal.sh里添加如下代码&#xff1a; #!/bin/bashexport TERMlinux 然后同步文件到内存&#xff1a; source /etc/profile

ACM训练题:互不侵犯

一看数据范围&#xff0c;如果是枚举所有的棋盘情况&#xff0c;2^K&#xff0c;肯定超了&#xff0c;自然是要一行一行递推&#xff0c;而相邻这个情况用位运算会比较方便&#xff0c;所以用状压dp。 具体算法&#xff1a;dp[i][j][k]表示第i行&#xff0c;前i行有j个棋子&…

【网站项目】023实验室耗材管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

去空行小工具Html + Javascript

这是一个平常用到的小工具&#xff0c;为了节省屏幕空间把空行去掉&#xff0c;怕要用的时候找不到故记录在此。 效果图 网页版&#xff0c;放在浏览器里就可以用 <!doctype html> <html><head><meta charset"utf-8"><title>去回车…

九、OpenCV自带colormap

项目功能实现&#xff1a;每隔1500ms轮流自动播放不同风格图像显示&#xff0c;按下Esc键退出 按照之前的博文结构来&#xff0c;这里就不在赘述了 一、头文件 colormap.h #pragma once #include<opencv2/opencv.hpp> using namespace cv;class ColorMap { public:vo…

Spring 如何解决循环依赖?Spring三级缓存

什么是循环依赖 说白是一个或多个对象实例之间存在直接或间接的依赖关系&#xff0c;这种依赖关系构成了构成一个环形调用。 自己依赖自己 两个对象间的依赖关系 多个对象间的依赖关系 Spring出现循环依赖的场景 单例的setter注入 Service public class A {Resourceprivate…

flask+python儿童福利院管理系统pycharm毕业设计项目

本系统解决了儿童福利院管理事务中的主要问题&#xff0c;包括首页、个人中心、爱心人士管理、员工管理、后勤人员管理、儿童信息管理、院所风采管理、活动管理、食谱管理、领养流程管理、政策法规管理、楼栋管理、宿舍管理、领养申请管理、义工申请管理、捐赠信息管理、宿舍物…

linux应用 进程间通信之共享内存(POSIX)

1、前言 1.1 定义 POSIX共享内存是一种在UNIX和类UNIX系统上可用的进程间通信机制。它允许多个进程共享同一块内存区域&#xff0c;从而可以在这块共享内存上进行读写操作。 1.2 应用场景 POSIX共享内存适用于需要高效地进行大量数据交换的场景&#xff0c;比如多个进程需要…

消息中间件特点

1.  消息中间件概念 消息中间件是消息传递的过程中保存消息的容器。 主要目的&#xff1a;提供路由并保证消息的传递&#xff1b;如果发送消息时接受者不可用&#xff0c;消息队列会保留信息&#xff0c;直到可以成功传递为止。 消息中间件保存消息也是有期限的。 2.  消息…

openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存

文章目录 openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存217.1 查看内存状况217.2 性能参数分析 openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存 获取openGauss节点的CPU、内存、I/O和网络资源使用情况&…

加固平板电脑丨三防智能平板丨工业加固平板丨智能城市管理

随着智能城市的不断发展&#xff0c;人们对于城市管理的要求也在不断提高&#xff0c;这就需要高效、智能的城市管理平台来实现。而三防平板就是一款可以满足这一需求的智能设备。 三防平板是一种集防水、防尘、防摔于一体的智能平板电脑&#xff0c;它可以在复杂的环境下稳定运…

《Think in Java》

《Think in Java》 第一章&#xff1a;对象导论 1.1 抽象过程 1&#xff09;万物皆对象。 2&#xff09;程序是对象的集合&#xff0c;它们通过发送消息来告诉彼此所要做的。 3&#xff09;每个对象都有其他对象构成的存储&#xff0c;一个对象可以复用其他对象&#xff0c;从而…

【C++】模版初阶

目录 泛函编程 函数模版 概念 格式 原理 实例化 模版函数的匹配原则 类模板 定义格式 泛函编程 如何实现一个通用的交换函数呢&#xff1f; void Swap(int& left, int& right) {int temp left;left right;right temp; } void Swap(double& left, dou…

搜索专项---最小步数模型

文章目录 魔板 一、魔板OJ链接 本题思路:最小步数模型: 将整个“图”视为一个状态也即一个节点. 状态的转移视为权值为1的边. BFS求解, 注意几点: 状态的存储: 一般用字符串存储状态, 用哈希表存储初始状态到每个状态的距离. 方案记录: 记忆数组存储. 本题中需要存储上一个状…