回溯算法解决组合问题

文章目录

  • 回溯算法
    • 组合问题
    • 回溯算法在组合问题上的运用
    • 例题
      • Leetcode 77. 组合
      • Leetcode 216. 组合总和 III
      • Leetcode 17. 电话号码的字母组合


回溯算法

回溯算法是一种搜索方式,本质上其实就是穷举出所有可能,然后筛选出我们想要的答案。

回溯算法的效率并不高,但是能解决一些暴力搜索解决不了的问题,比如组合问题。

组合问题

组合问题:在n个数里面按一定规则找出k个数的集合。

组合与排列的区别:组合是不强调元素顺序的,排列是强调元素顺序。

简单的、数据小的组合问题可以通过暴力解决,比如在10个数中找出2个数的组合,只需要2个for循环嵌套就可以解决。

for(i = 0; i < n; i++)
{
	for(j = i + 1; j < n; j++)
	{
		//i与j排列组合
	}
}

但是如果涉及到更大的数据时,比如在100个数里找出50个数的组合,我们就需要50个for循环嵌套,这样的问题就不能通过暴力去解决。

回溯算法在组合问题上的运用

具体思路如下图:
思路图
代码模板:

 void dfs(int cur, int n, int k)
 {
    if()//当条件满足判断时,说明我们得到一个符合条件的结果
    {
        //将该结果储存起来
        return;//返回函数上一级去尝试下一种可能
    }
    for(){
		//通过for循环横向遍历需要处理的结点
		dfs(下一个结点)//递归,用同样的方法去处理该节点的下一个结点
		//撤销处理过的结点
	}
 }

例题

Leetcode 77. 组合

给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

示例 1:
输入:n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]

示例 2:
输入:n = 1, k = 1
输出:[[1]]

提示:
1 <= n <= 20
1 <= k <= n

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
 int *temp; //用来存放某一条组合
 int tempsize;
 int **ret; //用来存放符合条件的结果
 int retsize;
 void dfs(int cur, int n, int k)
 {
    if(tempsize == k)//满足条件当某一条组合中元素的数量达标,将该结果存入ret中
    {
        int *tmp = malloc(sizeof(int) * k);
        for(int i = 0; i < k; i++)
        {
            tmp[i] = temp[i];
        }
        ret[retsize++] = tmp;
        return;//返回上一层函数
    }
    int j;
    for(j = cur; j <=n ;j++) {
        temp[tempsize++] = j;//将一个新的可能放入组合中
        dfs(j + 1, n, k);//递归,完善这个可能
        tempsize--;//回溯,撤销处理过的可能
    }
 }
int** combine(int n, int k, int* returnSize, int** returnColumnSizes) {
    temp = (int*)malloc(sizeof(int) * k);
    ret = (int **)malloc(sizeof(int*) * 20);
    tempsize = 0;
    retsize = 0;
    dfs(1, n, k);
    *returnSize = retsize;
    *returnColumnSizes = malloc(sizeof(int) * retsize);
    for (int i = 0; i < retsize; i++) {
        (*returnColumnSizes)[i] = k;
    }
    return ret;
}

Leetcode 216. 组合总和 III

找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:

  • 只使用数字1到9
  • 每个数字 最多使用一次
  • 返回所有可能的有效组合的列表。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

示例 1:
输入: k = 3, n = 7
输出: [[1,2,4]]
解释:
1 + 2 + 4 = 7
没有其他符合的组合了。

示例 2:
输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
解释:
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
没有其他符合的组合了。

示例 3:
输入: k = 4, n = 1
输出: []
解释: 不存在有效的组合。在[1,9]范围内使用4个不同的数字,我们可以得到的最小和是1+2+3+4 = 10,因为10 > 1,没有有效的组合。

提示:
2 <= k <= 9
1 <= n <= 60

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
 int **ret;
 int retsize;
 int *temp;
 int tempsize;
 void dfs(int p, int k, int n, int sum)
 {
    if(tempsize == k)
    {
        if(sum == n)
        {
            int *tmp = malloc(sizeof(int) * k);
            for(int i = 0; i < k; i++)
            {
                tmp[i] = temp[i];
            }
            ret[retsize++] = tmp;
        }
        return;
    }
    int j;
    for(j = p; j <=9 ;j++)
    {
        temp[tempsize++] = j;
        sum += j;
        dfs(j + 1, k, n, sum);
        tempsize--;
        sum -= j;
    }
 }
int** combinationSum3(int k, int n, int* returnSize, int** returnColumnSizes) {
    retsize = 0;
    tempsize = 0;
    temp = (int*)malloc(sizeof(int) * k);
    ret = (int **)malloc(sizeof(int*) * 20);
    dfs(1, k, n, 0);
    *returnSize = retsize;
    *returnColumnSizes = (int*)malloc(sizeof(int) * retsize);
    for (int i = 0; i < retsize; i++)
    {
        (*returnColumnSizes)[i] = k;
    }
    return ret;
}

Leetcode 17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例图
示例 1:
输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]

示例 2:
输入:digits = “”
输出:[]

示例 3:
输入:digits = “2”
输出:[“a”,“b”,“c”]

提示:
0 <= digits.length <= 4
digits[i] 是范围 [‘2’, ‘9’] 的一个数字。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
 char* temp;
int tempsize;
char** ret;
int retsize;
 char* letterMap[10] = {"", 
        "", 
        "abc", 
        "def", 
        "ghi", 
        "jkl",
        "mno", 
        "pqrs", 
        "tuv", 
        "wxyz", 
};
void dfs(char *digits, int cur)
{
    if(tempsize == strlen(digits))
    {
        char *tmp = (char *)malloc(sizeof(char) * (strlen(digits) + 1));
        int i;
        for(i = 0; i < strlen(digits); i++)
        {
            tmp[i] = temp[i];
        }
        tmp[i] = '\0';
        ret[retsize++] = tmp;
        return;
    }
    int num = digits[cur] - '0';
    char *table = letterMap[num];
    for(int j = 0; j < strlen(table); j++)
    {
        temp[tempsize++] = table[j];
        dfs(digits, cur + 1);
        tempsize--;
    }
}
char** letterCombinations(char* digits, int* returnSize) {
    int n = strlen(digits);
    *returnSize = 0;
    if(n == 0)
    {
        return "";
    }
    ret = malloc(sizeof(int*) * 2000);
    temp = malloc(sizeof(int) * n);
    tempsize = 0;
    retsize = 0;
    dfs(digits, 0);
    *returnSize = retsize;
    return ret;
}

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

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

相关文章

mac M2 配置item2 rzsz

背景 apple m 系列处理器安装的 homebrew 跟 intel 处理器略有不同&#xff0c;其中安装目录的区别&#xff1a; m 系列处理器安装目录为 /usr/local/bin/homebrew intel 处理器安装目录为 /opt/homebrew 问题1: 卡住 产生原因&#xff1a; m 系列使用 brew install lrzs…

红米A2/A2+/POCO C51手机秒解BL+快速获取root权限+解谷歌锁刷机救砖教程

红米A2/A2/POCO C51手机是目前小米公司针对于国外用户的1个独立的品牌&#xff0c;或者和国内的红米手机都非常相似&#xff0c;几款手机由于硬件非常接近&#xff0c;我们这里将其放在一起和大家介绍而从他们的代号中我们可以得知&#xff0c;目前A2/POCO的代号为water&#x…

图像置乱加密-Arnold加密算法

置乱加密是另一种较常用的加密方法&#xff0c;现也被许多文献选用&#xff0c;置乱加密可以是以像素为单位进行全局置乱&#xff0c;该方式打乱了图像像素值的位置&#xff0c;使其图像内容失去相关性&#xff0c;达到保护的目的。也可以是以块为单位进行置乱&#xff0c;该方…

MT3608B 航天民芯代理 1.2Mhz 24V输入 升压转换器

深圳市润泽芯电子有限公司为航天民芯一级代理商 技术支持欢迎试样~Tel&#xff1a;18028786817 简述 MT3608B是恒定频率的6针SOT23电流模式升压转换器&#xff0c;用于小型、低功耗应用。MT3608B开关频率为1.2MHz&#xff0c;允许使用微小、低电平成本电容器和电感器高度不…

机器学习:基于Sklearn、XGBoost框架,使用XGBClassifier、支持向量分类器和决策树分类器预测乳腺癌是良性还是恶性

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

通过反汇编深入理解栈

若想更好地理解函数的多级调用、线程切换其本质&#xff0c;都需要对栈有更加深入的认识。 一、如何生成反汇编 在上图框中输入 fromelf --text -a -c --outputtest.dis xxx.axf // 把下图中的axf文件&#xff08;包括路径&#xff09;替换掉 "xxx.axf"然后编译即可…

弹性网络回归(概念+实例)

目录 前言 一、基本概念 1. 弹性网络回归的原理 2. 弹性网络回归的优点 3. 弹性网络回归的应用 4. 弹性网络回归的调参 二、实例 前言 弹性网络回归&#xff08;Elastic Net Regression&#xff09;是一种用于处理回归问题的机器学习算法&#xff0c;它结合了岭回归&…

Jmeter05:配置环境变量

1 Jmeter 环境 1.1 什么是环境变量&#xff1f;path什么用&#xff1f; 系统设置之一&#xff0c;通过设置PATH&#xff0c;可以让程序在DOS命令行直接启动 1.2 path怎么用 如果想让一个程序可以在DOS直接启动&#xff0c;需要将该程序目录配置进PATH 1.3 PATH和我们的关系…

基于光伏电站真实数据集的深度学习预测模型(Python代码,深度学习五个模型)

效果视频链接&#xff1a;基于深度学习光伏预测系统&#xff08;五个模型&#xff09;_哔哩哔哩_bilibili 界面设计 注册界面 登录界面 主界面 展示界面 1.数据集来源 The SOLETE dataset 这里分别保存了不同间隔采样时间表格 1min是以1min 间隔采集的数据集 数据集截图&…

测算sample gpt

测算代码 import pandas as pd import matplotlib.pyplot as pltlosspd.read_pickle("loss_8.pkl") plt.plot(loss) losspd.read_pickle("loss_16.pkl") plt.plot(loss) losspd.read_pickle("loss_4_8.pkl") plt.plot(loss) losspd.read_pickle(…

因泰立科技交付宁波北收费站激光车辆检测器,实现车辆的精准分离

因泰立科技交付宁波北收费站ETC收费系统所需激光车辆检测器&#xff0c;实现车辆的精准分离&#xff0c;助力高速公路更加畅通、便捷。 此次交付的是因泰立科技的爆款产品&#xff1a;ILS-E20-3 激光车辆检测器&#xff0c;可以单侧安装&#xff0c;避免破地等大量工程安装工作…

利用Triple U.Net结构对冷冻切片HE染色组织学图像进行核实例分割

利用Triple U.Net结构对冷冻切片H&E染色组织学图像进行核实例分割 摘要IntroductionRelated WorksDatasetProposed MethodologyDataset PreparationSegmentation BranchLoss FunctionWatershed Algorithm Nuclei Instance Segmentation of Cryosectioned H&E Stained H…

【人工智能基础】逻辑回归实验分析

实验环境&#xff1a;anaconda、jutpyter Notebook 实验使用的库&#xff1a;numpy、matplotlib 一、逻辑回归 逻辑回归是一个常用于二分类的分类模型。本质是&#xff1a;假设数据服从这个分布&#xff0c;然后使用极大似然估计做参数的估计。 二、实验准备 引入库、预设值…

C++-DAY5

有以下类&#xff0c;完成特殊成员函数 #include <iostream>using namespace std; class Person {string name;int *age; public://有参构造Person(string name,int age):name(name),age(new int(age)){}//析构函数~Person(){delete age;}//拷贝构造Person(const Person …

FreeRTOS-系统时钟节拍和时间管理

一、前言 任何操作系统都需要提供一个时钟节拍&#xff0c;以供系统处理诸如延时&#xff0c;超时等与时间相关的事件。时钟节拍是特定的周期性中断&#xff0c; 这个中断可以看做是系统心跳。 中断之间的时间间隔取决于不同的应用&#xff0c;一般是 1ms – 100ms。时钟的节拍…

GQA分组注意力机制

一、目录 定义demo 二、实现 定义 grouped query attention&#xff08;GQA&#xff09; 1 GQA 原理与优点&#xff1a;将query 进行分组&#xff0c;每组query 参数共享一份key,value, 从而使key, value 矩阵变小。 2. 优点&#xff1a; 降低内存读取模型权重的时间开销&am…

无缝迁移:从阿里云WAF到AWS的成功转变之路

在当今数字化浪潮中&#xff0c;网络安全已经成为企业发展的重要组成部分。阿里云WAF&#xff08;Web 应用防火墙&#xff09;作为一种重要的网络安全解决方案&#xff0c;帮助企业保护其 Web 应用免受各种网络攻击。 然而&#xff0c;随着企业业务的扩展和需求的变化&#xf…

可替代IBM DOORS的现代化需求管理解决方案Jama Connect,支持数据迁移及重构、实时可追溯性、简化合规流程

作为一家快速发展的全球性公司&#xff0c;dSPACE一直致力于寻找保持领先和优化开发流程的方法。为推进其全球现代化计划&#xff0c;dSPACE开始寻找可以取代传统需求管理平台&#xff08;IBM DOORS&#xff09;的需求管理解决方案。 通过本次案例&#xff0c;您将了解dSPACE为…

数据结构-简单队列

1.简介 队列为一个有序列表&#xff0c;可以用数组或链表来实现。 先进先出原则。先存入队列的数据先取出&#xff0c;后存进队列的数据后取出。 这里对比一下&#xff0c;栈是后来者居上 下面使用数组来模拟队列&#xff0c;用数组的结构来存储队列的数据&#xff1a; Que…

Stable Diffusion教程:额外功能/后期处理/高清化

"额外功能"对应的英文单词是Extras&#xff0c;算是直译。但是部分版本中的翻译是“后期处理”或者“高清化”&#xff0c;这都是意译&#xff0c;因为它的主要功能是放大图片、去噪、修脸等对图片的后期处理。注意这里边对图片的处理不是 Stable Diffusion 本身的能…