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

news2024/11/26 12:41:07

算法学习——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);
    }
};

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

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

相关文章

python 基础知识点(蓝桥杯python科目个人复习计划41)

今日复习内容&#xff1a;动态规划&#xff08;基础&#xff09; 动态规划是一种解决多阶段决策过程中最优化问题的数学方法和算法思想。它通常用于解决具有重叠子问题和最优子结构性质的问题&#xff0c;通常将问题划分为相互重叠的子问题&#xff0c;利用子问题的解来求解原…

机器学习3----决策树

这是前期准备 import numpy as np import pandas as pd import matplotlib.pyplot as plt #ID3算法 #每个特征的信息熵 # target : 账号是否真实&#xff0c;共2种情况 # yes 7个 p0.7 # no 3个 p0.3 info_D-(0.7*np.log2(0.7)0.3*np.log2(0.3)) info_D #日志密度…

一周学会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…

Cocos2dx-lua ScrollView[一]基础篇

一.ScrollView概述 cocos游戏中ScrollView控件大量使用,95%以上的项目都会使用ScrollView,个别游戏可能全部使用翻页的滑动效果。如果想要精通Cocos的UI开发,精通ScrollView控件非常关键,因此对ScrollView的使用进行总结很有必要。 下文缩写说明:sv = ScrollView, item代…

Python Matplotlib 的学习笔记

Python Matplotlib 的学习笔记 0. Python Matplotlib 简介1. 为什么要用 Matplotlib&#xff1f;2. Matplotlib 基础类详解2-1. Line&#xff08;线&#xff09;2-2. Marker&#xff08;标记&#xff09;2-3. Text&#xff08;文本&#xff09;2-4. Legend&#xff08;图例&…

数据结构实验三 图的深度优先搜索(包含求连通分量)

全屏浏览作者 王群芳 单位 合肥师范学院 以邻接矩阵作存储结构&#xff0c;编写程序对给定的无向图&#xff08;图中包含n个顶点&#xff0c;编号为0至n-1&#xff09;进行深度优先遍历&#xff0c;并在遍历的过程中计算图G的连通分量个数及边的数目。 本题限定在遍历过程中…

车载软件架构 —— Adaptive AUTOSAR软件架构

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师&#xff08;Wechat&#xff1a;gongkenan2013&#xff09;。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 本就是小人物&#xff0c;输了就是输了&#…

蓝桥杯:C++排序

排序 排序和排列是算法题目常见的基本算法。几乎每次蓝桥杯软件类大赛都有题目会用到排序或排列。常见的排序算法如下。 第(3)种排序算法不是基于比较的&#xff0c;而是对数值按位划分&#xff0c;按照以空间换取时间的思路来排序。看起来它们的复杂度更好&#xff0c;但实际…

数模.传染病模型plus

一、SIS模型 二、SIR模型 三、SIRS模型 四、SEIR模型

Python第十六章(面向对象)

类&#xff1a;是对一系列相同特征和行为的事物的统称&#xff0c;是一个抽象的概念&#xff0c;不是真实存在的事物 特征&#xff1a;属性/变量 行为&#xff1a;方法/函数 对象&#xff1a;类创建出来的真实事物 类和对象的关系&#xff1a;先构造一个类&#xff0…

GitHub项目推荐-InstantID

项目地址 https://github.com/InstantID/InstantID 项目简述 InstantID是一个图生图项目&#xff0c;仅仅通过一张正脸的图片&#xff0c;就能生成各种风格的人像。该项目的文档描述比较齐备&#xff0c;所以复现起来成本比较小。 项目截图 这是项目介绍中的一张截图&…

二叉树基础总结

目录 树的定义&#xff1a; 深度和高度&#xff1a; 二叉树 由来 二叉树种类&#xff1a; 满二叉树&#xff1a; 完全二叉树&#xff1a; 严格二叉树&#xff08;Strict Binary Tree&#xff09;&#xff1a; 平衡二叉树&#xff08;Balanced Binary Tree&#xff09;&…

【阅读笔记】空域保边降噪《Side Window Filtering》

1、保边滤波背景 保边滤波器的代表包括双边滤波、引导滤波&#xff0c;但是这类滤波器有一个问题&#xff0c;它们均将待处理的像素点放在了方形滤波窗口的中心。但如果待处理的像素位于图像纹理或者边缘&#xff0c;方形滤波核卷积的处理结果会导致这个边缘变模糊。 基于这个…

算法刷题:有效三角形个数

有效三角形个数 .题目链接题目详情算法原理补充知识点双指针:对撞指针 我的答案 . 题目链接 有效三角形个数 题目详情 算法原理 补充知识点 有效三角形需要满足的条件: ab>cac>bbc>a 其实在满足1的时候,c是最大的,那么2和3是显然成立的,因此我们可以这样解题: 对…

【北邮鲁鹏老师计算机视觉课程笔记】10 Classification 分类

【北邮鲁鹏老师计算机视觉课程笔记】10 Classification 分类 1 图像识别的基本范式 检测问题&#xff1a;不仅要知道有没有&#xff0c;还要知道在哪里 分类是整图级标签&#xff0c;检测是区域级标签&#xff0c;分割是像素级标签 2 检测任务的应用 3 单实例识别与类别识别…

九、OpenCV自带colormap

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

Rust 数据结构与算法:1算法分析之乱序字符串检查

Rust 数据结构与算法 一、算法分析 算法是通用的旨在解决某种问题的指令列表。 算法分析是基于算法使用的资源量来进行比较的。之所以说一个算法比另一个算法好,原因就在于前者在使用资源方面更有效率,或者说前者使用了更少的资源。 ●算法使用的空间指的是内存消耗。算法…

浅谈业务场景中缓存的使用

业务场景中缓存的使用 一、背景二、缓存分类1.本地缓存2.分布式缓存 三、缓存读写模式1.读请求2.写请求 四、缓存穿透1.缓存空对象2.请求校验3.请求来源限制4.布隆过滤器 五、缓存击穿1.改变过期时间2.串行访问数据库 六、缓存雪崩1.避免集中过期2.提前更新缓存 七、缓存与数据…

初始JAVA

目录 一、输出HelloWorld 1.1开发步骤 1.2 编写 1.3 编译 1.4 运行 二、 HelloWorld小结 2.1 Java程序的结构与格式 2.2 Java程序的入口 2.3 两种常见的输出语句 2.4 源文件名与类名 三、 注释(comment) 四、 Java API文档 五、 Java核心机制&#xff1a;JVM 5.1…

OpenAI宣布ChatGPT新增记忆功能;谷歌AI助理Gemini应用登陆多地区

&#x1f989; AI新闻 &#x1f680; OpenAI宣布ChatGPT新增记忆功能&#xff0c;可以自由控制内存&#xff0c;提供个性化聊天和长期追踪服务 摘要&#xff1a;ChatGPT新增的记忆功能可以帮助AI模型记住用户的提问内容&#xff0c;并且可以自由控制其内存。这意味着用户不必…