【leetcode】深搜、暴搜、回溯、剪枝(C++)2

news2024/11/26 10:45:45

深搜、暴搜、回溯、剪枝(C++)2

  • 一、括号生成
    • 1、题目描述
    • 2、代码
    • 3、解析
  • 二、组合
    • 1、题目描述
    • 2、代码
    • 3、解析
  • 三、目标和
    • 1、题目描述
    • 2、代码
    • 3、解析
  • 四、组合总和
    • 1、题目描述
    • 2、代码
    • 3、解析
  • 五、字母大小写全排列
    • 1、题目描述
    • 2、代码
    • 3、解析
  • 六、优美的排列
    • 1、题目描述
    • 2、代码
    • 3、解析
  • 七、N皇后
    • 1、题目描述
    • 2、代码
    • 3、解析
  • 八、有效的数独
    • 1、题目描述
    • 2、代码
    • 3、解析


一、括号生成

1、题目描述

leetcode链接
在这里插入图片描述

2、代码

class Solution 
{
public:
    // 1、全局变量
    string path;
    vector<string> ret;
    int right = 0, left = 0, n = 0;
    vector<string> generateParenthesis(int _n) 
    {
        n = _n;
        dfs();
        return ret;
    }
    void dfs()
    {
        // 1、出口
        if(right == n)
        {
            ret.push_back(path);
            return;
        }
        // 2、添加左括号
        if(left < n)
        {
            path.push_back('(');
            left++;
            dfs();
            path.pop_back(); // 恢复现场
            left--;
        }
        if(right < left) // 3、添加右括号
        {
            path.push_back(')');
            right++;
            dfs();
            path.pop_back(); // 恢复现场
            right--;
        }
    }
};

3、解析

在这里插入图片描述

二、组合

1、题目描述

leetcode链接

在这里插入图片描述

2、代码

class Solution 
{
public:
    // 1、全局变量
    int n = 0; // 1-n
    int k = 0; // 几个数
    vector<int> path; // 路径
    vector<vector<int>> ret; // 增加的路径函数
    vector<vector<int>> combine(int _n, int _k) 
    {
        n = _n;
        k = _k;
        dfs(1); // 2、dfs
        return ret;
    }
    void dfs(int _pos)
    {
        // 1、函数递归出口
        if(path.size() == k)
        {
            ret.push_back(path);
            return;
        }
        // 2、遍历--剪枝
        for(int pos = _pos; pos <= n; pos++)
        {
            path.push_back(pos);
            dfs(pos + 1); // pos下一个数进行递归实现剪枝
            path.pop_back(); // 回溯--恢复现场         
        }
    }
};

3、解析

在这里插入图片描述

三、目标和

1、题目描述

leetcode链接
在这里插入图片描述

2、代码

全局变量的超时代码:
原因在于nums的长度最长有20,其2^20次方太大了。但是leetcode居然通过了。

class Solution 
{
public:
    // 1、全局变量
    int ret; // 返回
    int aim; // 目标值
    int path; // 路径
    int findTargetSumWays(vector<int>& nums, int target) 
    {
        aim = target;
        dfs(nums, 0);
        return ret;
    }
    void dfs(vector<int>& nums, int pos)
    {
        // 1、递归出口
        if(pos == nums.size())
        {
            if(path == aim)
            {
                ret++;
            }
            return;
        }
        // 2、加法
        path += nums[pos];
        dfs(nums, pos + 1);
        path -= nums[pos]; // 恢复现场
        // 3、减法
        path -= nums[pos];
        dfs(nums, pos + 1);
        path += nums[pos]; // 恢复现场
    }
};

path作为参数的正确代码:

class Solution 
{
public:
    // 1、全局变量
    int ret; // 返回
    int aim; // 目标值
    int findTargetSumWays(vector<int>& nums, int target) 
    {
        aim = target;
        dfs(nums, 0, 0);
        return ret;
    }
    void dfs(vector<int>& nums, int pos, int path)
    {
        // 1、递归出口
        if(pos == nums.size())
        {
            if(path == aim)
            {
                ret++;
            }
            return;
        }
        // 2、加法
        path += nums[pos];
        dfs(nums, pos + 1, path);
        path -= nums[pos]; // 恢复现场
        // 3、减法
        path -= nums[pos];
        dfs(nums, pos + 1, path);
        path += nums[pos]; // 恢复现场
    }
};

3、解析

在这里插入图片描述

四、组合总和

1、题目描述

leetcode链接
在这里插入图片描述

2、代码

解法一:

class Solution 
{
public:
    // 1、全局变量
    vector<vector<int>> ret; // 返回
    vector<int> path; // 路径
    int aim; // 记录target
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) 
    {
        aim = target;
        dfs(candidates, 0, 0);
        return ret;
    }
    void dfs(vector<int>& nums, int pos, int sum)
    {
        // 1、递归出口
        if(sum == aim)
        {
            ret.push_back(path);
            return;
        }
        if(sum > aim)
        {
            return;
        }
        // 循环
        for(int i = pos; i < nums.size(); i++)
        {
            path.push_back(nums[i]);
            sum += nums[i];
            dfs(nums, i, sum); // 还是从开始
            path.pop_back(); // 恢复现场
            sum -= nums[i];
        }
    }
};

解法二:

class Solution 
{
public:
    // 1、全局变量
    vector<vector<int>> ret; // 返回
    vector<int> path; // 路径
    int aim; // 记录target
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) 
    {
        aim = target;
        dfs(candidates, 0, 0);
        return ret;
    }
    void dfs(vector<int>& nums, int pos, int sum)
    {
        // 1、递归出口
        if(sum == aim)
        {
            ret.push_back(path);
            return;
        }
        if(sum > aim || pos == nums.size())
        {
            return;
        }
        // 循环
        for(int k = 0; k * nums[pos] + sum <= aim; k++)
        {
            if(k)
            {
                path.push_back(nums[pos]);
            }
            dfs(nums, pos + 1, sum + k * nums[pos]);
        }
        // 恢复现场
        for(int k = 1; k * nums[pos] + sum <= aim; k++)
        {
            path.pop_back();
        }
    }
};

3、解析

解法一:
在这里插入图片描述
解法二:
在这里插入图片描述

五、字母大小写全排列

1、题目描述

leetcode链接
在这里插入图片描述

2、代码

class Solution 
{
public:
    // 全局变量
    string path; // 路径
    vector<string> ret; // 返回
    vector<string> letterCasePermutation(string s) 
    {
        dfs(s, 0); // 将s这个字符串的第0个位置进行传参
        return ret;
    }
    void dfs(string s, int pos)
    {
        // 递归出口
        if(pos == s.length())
        {
            ret.push_back(path);
            return;
        }
        // 先记录一下当前的字母
        char ch = s[pos];
        // 不改变
        path.push_back(ch);
        dfs(s, pos + 1);
        path.pop_back(); // 恢复现场
        // 改变
        if(ch < '0' || ch > '9')
        {
            // 进行改变大小写函数
            ch = Change(ch);
            path.push_back(ch);
            dfs(s, pos + 1); // 往下一层递归
            path.pop_back(); // 恢复现场
        }
    }
    char Change(char ch)
    {
        if(ch >= 'a' && ch <= 'z')
        {
            ch -= 32;
        }
        else
        {
            ch += 32;
        }
        return ch;
    }
};

3、解析

在这里插入图片描述

六、优美的排列

1、题目描述

leetcode链接
在这里插入图片描述

2、代码

class Solution 
{
public:
    // 全局变量
    int ret; // 返回
    bool check[16]; // 判断相对应位置是true还是false
    int countArrangement(int n) 
    {
        dfs(1, n); // 下标从1开始
        return ret;
    }
    void dfs(int pos, int n)
    {
        // 递归出口
        if(pos == n + 1) // 因为是从1开始的
        {
            ret++; // 只用做数的统计即可
            return;
        }
        // 循环
        for(int i = 1; i <= n; i++)
        {
            if(check[i] == false && (pos % i == 0 || i % pos == 0))
            {
                check[i] = true; // 表示用了
                dfs(pos + 1, n); // 递归到下一层
                check[i] = false; // 恢复现场
            }
        }
    }
};

3、解析

在这里插入图片描述

七、N皇后

1、题目描述

leetcode链接

在这里插入图片描述

2、代码

class Solution 
{
public:
    // 全局变量
    bool checkcol[10]; // 列
    bool checkG1[20]; // 主对角线
    bool checkG2[20]; // 副对角线
    vector<string> path; // 路径
    vector<vector<string>> ret; // 返回
    int n; // 全局变量n
    vector<vector<string>> solveNQueens(int _n) 
    {
        n = _n;
        // 初始化棋盘
        path.resize(n);
        for(int i = 0; i < n; i++)
        {
            path[i].append(n, '.');
        }
        dfs(0);
        return ret;
    }
    void dfs(int row) // 行
    {
        // 递归出口
        if(row == n)
        {
            ret.push_back(path);
            return;
        }
        for(int col = 0; col < n; col++) // 每一行所在的列位置
        {
            if(checkcol[col] == false/*一整列*/ && checkG1[row - col + n] == false/*y-x+n*/ && checkG2[row + col] == false/*y+x*/) // 判断条件进入
            {
                path[row][col] = 'Q';
                checkcol[col] = checkG1[row - col + n] = checkG2[row + col] = true;
                dfs(row + 1);
                // 恢复现场
                path[row][col] = '.';
                checkcol[col] = checkG1[row - col + n] = checkG2[row + col] = false;
            }
        }
    }
};

3、解析

这里我们着重在剪枝方面上面的讲解,我们重点需要明白N皇后剪枝的作用,因为皇后是能吃横的一整行,竖的一整列,主对角线和副对角线一整个,这里原本是要循环四次,但是我们经过想法发现其实只需要判断三个位置即可,第一个位置是竖着的,第二个位置是主对角线,第三个位置是副对角线,因为横着的一行是不需要进行判断的,因为我们的思路是以一整行为一个视角,从左往右依次填的!我们根据简单的数学原理,主对角线是y=x+b的,而由于会出现负数情况,我们左右两边各加一个n即可,我们此时b就为:y-x+n。我们副对角线是y=-x+b,我们的b为y+x即可!那我们接下来的思路画出决策树以后只需要考虑回溯的问题,我们恢复现场只需要将用过的全部变成没用过的即可。
在这里插入图片描述

八、有效的数独

1、题目描述

leetcode链接
在这里插入图片描述

2、代码

class Solution 
{
public:
    // 全局变量
    bool row[9][10]; // 行坐标加值
    bool col[9][10]; // 列坐标加值
    bool grid[3][3][10]; // 棋盘坐标加值
    bool isValidSudoku(vector<vector<char>>& board) 
    {
        for(int i = 0; i < 9; i++) // 行
        {
            for(int j = 0; j < 9; j++) // 列
            {
                if(board[i][j] != '.') // 数字的时候
                {
                    int num = board[i][j] - '0'; // 记录一下数
                    if(row[i][num] == true || col[j][num] == true || grid[i / 3][j / 3][num] == true)
                    {
                        return false;
                    }
                    row[i][num] = col[j][num] = grid[i / 3][j / 3][num] = true;
                }
            }
        }
        return true;
    }
};

3、解析

在这里插入图片描述

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

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

相关文章

【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱5(附带项目源码)

效果演示 文章目录 效果演示系列目录前言制作系统定义制作配方 源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第25篇中&#xff0c;我们将探索如何用unity制作一个3D背包、库存、制…

(四)【Jmeter】 JMeter的界面布局与组件概述

JMeter的界面布局 中文版&#xff1a; 英文版&#xff1a; JMeter的主界面包括菜单栏、工具栏、树形结构面板、视图面板等部分。 菜单栏&#xff1a;菜单栏包含了文件(File)、编辑(Edit)、查找(Search)、选项(Options)、工具(Tools)、帮助(Help)等菜单项&#xff0c;用于对…

Compose高级别API动画指南

前文讲了Compose中的低级别API动画&#xff0c;与之对应的&#xff0c;还有高级别API动画&#xff0c;同样也符合Material-Design规范。所有高级别动画 API 都是在低级别动画 API 的基础上构建而成&#xff0c;其对应关系如图&#xff1a; 接下来就对其高级别API逐个分析&…

2024LeetCode分类刷题

一、数组 88. 合并两个有序数组 public void merge(int[] nums1, int m, int[] nums2, int n) {int p1 0, p2 0;int[] sorted new int[m n];while (p1 < m || p2 < n) {int current;if (p1 m) {current nums2[p2];} else if (p2 n) {current nums1[p1];} else i…

单体工程结构

本文主要说明下单体项目的工程结构如何设计&#xff0c;目前业界存在两种主流的应用工程结构&#xff1a;一种是阿里推出的《Java开发手册》中推荐的&#xff0c;另外一种是基于DDD(领域驱动设计)推荐的。下面我们来看下两种工程结构是怎样的。 一、 基于阿里《Java开发手册》…

基于FPGA的UDP实现(包含源工程文件)

1、概括 前文通过FPGA实现了ARP和ICMP协议&#xff0c;ARP协议一般用来获取目的IP地址主机的MAC地址&#xff0c;ICMP通过回显请求和回显应答来判断以太网链路是否通畅&#xff0c;这两个协议都不是用来传输用户数据的。如果用户需要向PC端传输大量数据&#xff0c;那么就必须使…

Swift Combine 通过用户输入更新声明式 UI 从入门到精通十五

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

证明之缺角正方形网格的铺地砖问题

缺角正方形网格的铺地砖问题 “挑战难题&#xff1a;多米诺骨牌与无法覆盖的方格” 这里有个著名的难题。画八横八纵正方形网格&#xff0c;去掉相对的两个角。你能用多米诺骨牌形状的地砖——每一块正好覆盖两个相邻方格&#xff0c;把剩余部分覆盖吗&#xff1f;我在下图中…

bert-vits2本地部署报错疑难问题汇总

环境&#xff1a; bert-vits2.3 win 和wsl 问题描述&#xff1a; bert-vits2本地部署报错疑难问题汇总 解决方案&#xff1a; 问题1: Conda安装requirements里面依赖出现ERROR: No matching distribution found for opencc1.1.6 解决方法 需要在 Python 3.11 上使用 Op…

Springboot加载bootstrap和application原理

Springboot加载bootstrap和application原理 bootstrap.yml能被springboot加载导入依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.6</version><rel…

StringBuilder

StringBuilder代表可变字符串&#xff0c;相当于一个容器&#xff0c;里面的字符串可以改变&#xff0c;用来操作字符串。此类设计用作StringBuffer替代品。 构造方法&#xff1a; StringBuilder() StringBuilder(String str) 操作方法&#xff1a; 1. append()&#xff1…

【Spring】定义过滤器Filter和拦截器Interceptor

# 定义过滤器 package com.holen.filter;import jakarta.servlet.Filter; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; import java.io.IOException;pub…

2048游戏C++板来啦!

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 大家好呀&#xff0c;我是PingdiGuo_guo&#xff0c;今天我们来学习如何用C编写一个2048小游戏。 文章目录 1.2048的规则 2.步骤实现 2.1: 初始化游戏界面 2.1.1知识点 2.1.2: 创建游戏界面 2.2: 随机…

【开源】基于JAVA+Vue+SpringBoot的班级考勤管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统基础支持模块2.2 班级学生教师支持模块2.3 考勤签到管理2.4 学生请假管理 三、系统设计3.1 功能设计3.1.1 系统基础支持模块3.1.2 班级学生教师档案模块3.1.3 考勤签到管理模块3.1.4 学生请假管理模块 3.2 数据库设…

VS Code主题设置(美化VS Code)(主题+背景+图标+特效+字体)

目录 切换整体主题&#xff08;整体主题&#xff09; 切换文件图标主题 设置VS Code背景图案 字体特效 连击特效 字体设置 主题的具体效果放在了文章末尾&#xff0c;这篇文章后续也会进行更新 ————————————————————————————…

Vulnhub靶机:DC3

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;DC3&#xff08;10.0.2.56&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/dc-32,312…

get和set方法太多太臃肿?快使用 lombok

目录 0. lombok 介绍 1. lombok 使用 1.1 创建一个 maven 项目 1.2 在项目中引用依赖 1.3 在 idea 中添加 lombok 插件 1.4 使用 lombok 注解 1.5 Idea 运行报 Lombok requires enables annotation process 错误解决办法 0. lombok 介绍 当我们写一个类时&#xff0c;为了…

EsayExcel文件导入导出

目录 准备工作 监听器类 导入测试 导出测试 上传Excel 下载Excel 混合导出模板导出 headRowNumber(1)&#xff1a;从第几行开始读 准备工作 导入依赖 <!--easyexcel--> <dependency><groupId>com.alibaba</groupId>x<artifactId>easye…

微服务—ES数据同步

目录 数据同步 问题分析 方案1. 同步调用 方案2. 异步通知 方案3. 监听binlog​编辑 各方案对比 案例——利用MQ实现数据同步 步骤1. 导入hotel-admin项目 步骤2. 声明交换机、队列 步骤3. 发送MQ消息 步骤4. 接收MQ消息 步骤5. 测试同步功能 数据同步 elasticsea…

小白学Halcon100例:如何获取物品中心坐标并展示

文章目录 *读入彩色图片*分解彩色图片为三通道*阈值分割*链接*选择特征*提取目标中心*绘制目标中心--*设置线宽为1*创建十字轮廓*清空窗体*设置绘制模式为绘制边缘*显示目标*显示目标中心*读入彩色图片