回溯算法第一篇(子集树问题【三种思路】、0-1背包问题、最小重量机器设计问题)

目录

1. 子集树问题

解法一

解法二

解法三

2. 0-1背包问题(使用子集树解决)

3. 最小重量机器设计问题


1. 子集树问题

子集力扣链接

题目描述:给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例 1:

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:

输入:nums = [0]
输出:[[],[0]]

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10
  • nums 中的所有元素 互不相同

注:子集是不能重复的,例如{1,2,3}和{3,2,1}是一个子集。

解决方案如下:

解法一

算法策略为判断当前位置选还是不选,则决策树的形状是二叉树,决策树如下:

注:以下代码不是力扣那道题的正确代码,需要自行修改一些方法名,解法二的代码就可以在力扣运行且通过所有测试

import java.util.ArrayList;
import java.util.List;
//子集的第一种结果:叶子结点收集
public class SubsetTest {//设计全局变量static List<Integer> path;//用来临时接受一次自己的情况static List<List<Integer>> ret;//用来接收全部子集情况//nums:表示需要计算子集的数组//deep:表示第几层,也是表示nums数组的第几个元素,有两种选择,选还是不选public static void permute(int[] nums, int deep) {//1.初始化path = new ArrayList<>();ret = new ArrayList<>();//2.开始进行回溯算法dfs(nums, deep);}public static void output() {ret.add(new ArrayList<>(path));}public static void dfs(int[] nums, int deep) {//递归出口if (deep == nums.length) {output();return;} else {//这回溯的核心写成决策树,是一颗二叉树,因为有两种选择//(1)选path.add(nums[deep]);//进入下一层dfs(nums, deep + 1);//恢复现场:移除最后一个元素path.remove(path.size() - 1);//(2)不选,因为不选没有改变path集合,所以不需要恢复现场dfs(nums, deep + 1);}}public static void main(String[] args) {int[] nums = {1, 2, 3};permute(nums, 0);for (int i = 0; i < ret.size(); i++) {System.out.println(ret.get(i));}}
}

解法二

算法的策略相交于第一种解法有所不同,第一种解法是判断当前位置选不选的情况,所以决策树的叶子结点才是子集。

第二种解法是一棵多叉的决策树,是从一个子集的容量问题上来分情况,例如:子集里面的元素可以是0个、1个、2个,也可以是3个。具体如下所示:

class Solution {List<Integer> path;//用来记录一次的子集List<List<Integer>> ret;//用来记录总的子集情况public List<List<Integer>> subsets(int[] nums) {//1.初始化path = new ArrayList<>();ret = new ArrayList<>();//2.回溯的核心dfs(nums, 0);return ret;}//nums:需要计算子集的数组//deep:表示当前来到树的第几层public void dfs(int nums[], int deep) {//因为每一个结点都是我需要的结果,所以每一个结点都要收集ret.add(new ArrayList<>(path));//回溯开始//这里必须从deep开始,表示在nums数组中的第几位开始//只有这样,才不会导致重复选取for (int i = deep; i < nums.length; i++) {path.add(nums[i]);dfs(nums, i + 1);//恢复现场path.remove(path.size() - 1);}}
}


解法三

解法三是在解法一的思路上,加上一个boolean数组来判断当前位置选没选,决策树如下:

public class Test10 {static int N = 3;static char[] a = {'a', 'b', 'c'};static boolean[] x = {false, false, false};public static void main(String[] args) {backTrack(0);}
//回溯的核心public static void backTrack(int level) {if (level == N) {output();} else {x[level] = false;//不选backTrack(level + 1);x[level] = true;backTrack(level + 1);}}
//打印数据public static void output() {System.out.print("{");for (int i = 0; i < x.length; i++) {
//如果这个位置是选的话,也就是x[i] == true,就选a[i]if (x[i]) {System.out.print(a[i] + " ");}}System.out.print("}");System.out.println();}
}

2. 0-1背包问题(使用子集树解决)

题目描述:
你有⼀个背包,最多能容纳的体积是V。
现在有 n 个物品,第 i 个物品的体积为vi,价值为wi。
(1)求这个背包⾄多能装多⼤价值的物品
(2)若背包恰好装满,求⾄多能装多⼤价值的物品

true表示选这物品,false表示不选这物品

public class Test11 {static int C = 30;//背包容量static int N = 3;//三个物品static int weights[] = {16, 15, 15};//重量static int values[] = {45, 25, 25};//价值static boolean[] x = {false, false, false};//作为判断选不选的问题//保存最大价值static int maxValuse = 0;//回溯核心//w:当前背包所放物品重量和//v:当前背包所放物品价值和public static void backtrack(int level, int w, int v) {if (level == N) {output(v);} else {x[level] = false;//不选backtrack(level + 1, w, v);x[level] = true;//选if (legal(w + weights[level]))backtrack(level + 1, w + weights[level], v + values[level]);}}//判断当前背包重量是不是合法public static boolean legal(int w) {return w <= C;}//v:当前的价值public static void output(int v) {maxValuse = Math.max(v, maxValuse);}public static void main(String[] args) {backtrack(0, 0, 0);System.out.println(maxValuse);}
}

3. 最小重量机器设计问题

题目描述:设某一机器由 N 个部件组成,每一种部件都可以从 M 个不同的供应商处购得。设 W 是从供应商j处购得的部件i的重量, C 是相应的价格。 试设计一个算法,给出总价格不超过 D 的最小重量机器设计。

解决方案如下:

public class Test12 {static int N = 3;//部件数static int Suppliers = 3;//供应商数static int D = 4;//总价格限制static int minWeight = Integer.MAX_VALUE;//这个变量用来保存最小重量static int[][] weight = {{1, 2, 3}, {3, 2, 1}, {2, 1, 2}};//重量数组static int[][] value = {{1, 2, 3}, {3, 2, 1}, {2, 2, 2}};//价格数组static int[] str = new int[3];/*false表示选,true表示不选*///默认值是false//为什么是二维数组呢?因为要与w和v二维数组对应static boolean[][] flag = new boolean[3][3];//打印每个零件的供应商public static void output() {for (int i = 0; i < N; i++) {for (int j = 0; j < Suppliers; j++) {if (flag[i][j])str[i] = j + 1;}}}/*w:表示当前的重量v:表示当前的价值level:表示层数;0表示选第一个零件、1表示选第二个零件、2表示选第三个零件*/public static void backtrack(int level, int w, int v) {//能走到这个if肯定是没超过限制重量Dif (level == N) {int tmp = minWeight;minWeight = Math.min(minWeight, w);if (tmp != minWeight) {output();}} else {//表示从第一个供应商开始选择for (int i = 0; i < Suppliers; i++) {flag[level][i] = true;if (D >= v + value[level][i]) {backtrack(level + 1, w +weight[level][i], v + value[level][i]);}//这个为什么要改为false呢?//方便output方法的实现,找到每个零件的供应商flag[level][i] = false;}}}public static void main(String[] args) {backtrack(0, 0, 0);System.out.println("最小重量:" + minWeight);System.out.print("供应商顺序:");for (int i = 0; i < str.length; i++) {System.out.print(str[i] + " ");}}}

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

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

相关文章

NV040D语音芯片应用于取暖桌:智能语音提高用户体验

科技与生活的结合&#xff0c;是科技发展的展示。天气的降温&#xff0c;取暖桌越来越取得用户的心&#xff0c;时至今日传统的取暖桌已经没有办法满足用户的需求&#xff0c;智能语音取暖桌给用户的生活带来了不一样的体验。 NV040D语音芯片是一款性能稳定的芯片&#xff0c;拥…

XS9922B-国产cvi协议,满足国内车载视频传输领域国产化降本需求

XS9922B 是一款 4 通道模拟复合视频解码芯片&#xff0c;支持 HDCCTV 高清协议和 CVBS 标 清协议&#xff0c;视频制式支持 720P/1080P 高清制式和 960H/D1 标清制式。芯片将接收到的高清 模拟复合视频信号经过模数转化&#xff0c;视频解码以及 2D 图像处理之后&#xff0c;转…

Citespace、vosviewer、R语言的文献计量学可视化分析

文献计量学是指用数学和统计学的方法&#xff0c;定量地分析一切知识载体的交叉科学。它是集数学、统计学、文献学为一体&#xff0c;注重量化的综合性知识体系。特别是&#xff0c;信息可视化技术手段和方法的运用&#xff0c;可直观的展示主题的研究发展历程、研究现状、研究…

星座生肖运势配对+周公解梦流量主小程序源码系统 带完整的安装部署教程·

近年来&#xff0c;人们对于星座和生肖的配对以及周公解梦的需求越来越大。罗峰发现了一款集星座、生肖配对和周公解梦于一体的流量主小程序源码系统。该系统具有丰富的功能和易于部署的特点&#xff0c;旨在为广大用户提供更加便捷、高效的星座生肖配对和周公解梦服务。 以下…

差分法详解

前言 差分算法适用于一些需要对数组和序列进行增减、查询和更新操作的问题&#xff0c;可以提高计算效率和降低存储空间的需求。今天我将带大家学习如何使用差分法&#xff0c;会以例题来带大家使用差分法以增进理解。话不多说让我们开始吧&#xff01; 文章目录 一维差分尾声…

spring boot集成mybatis和springsecurity实现登录认证功能

参考了很多网上优秀的教程&#xff0c;结合自己的理解&#xff0c;实现了登录认证功能&#xff0c;不打算把理论搬过来&#xff0c;直接上代码可能入门更快&#xff0c;文中说明都是基于我自己的理解写的&#xff0c;可能存在表述或者解释不对的情况&#xff0c;如果需要理论支…

camunda流程引擎——Java集成Camunda(上)(笔记)

目录 一、以一个处理流程开始1.1 后端1.2 前端1.3 执行 二、Camunda的补充2.1 使用方式2.2 可视化平台的Cockpit2.3 流程相关数据2.4 表介绍2.5 前端集成Modeler 三、用Java集成Camunda3.1 集成配置3.2 自动部署3.2.1 修改process.xml位置3.2.2 多进程引擎配置与多租户 3.3 历史…

typedef的使用

在C语言中&#xff0c;有一个关键字叫做typedef&#xff0c;有些人对此感到很疑惑。不熟悉此知识的同学都会对编程失去细心&#xff0c;直接劝退&#xff08;因为之前我就是这样&#xff09;。、 因为好不容易认识了C语言中所有的关键字&#xff08;就是类型吧&#xff0c;像啥…

详细教程 - 从零开发 Vue 鸿蒙harmonyOS应用 第一节

关于使用Vue开发鸿蒙应用的教程,我这篇之前的博客还不够完整和详细。那么这次我会尝试写一个更加完整和逐步的指南,从环境准备,到目录结构,再到关键代码讲解,以及调试和发布等,希望可以让大家详实地掌握这个过程。 一、准备工作 下载安装 DevEco Studio 下载地址&#xff1a;…

逻辑回归的介绍和应用

逻辑回归的介绍 逻辑回归&#xff08;Logistic regression&#xff0c;简称LR&#xff09;虽然其中带有"回归"两个字&#xff0c;但逻辑回归其实是一个分类模型&#xff0c;并且广泛应用于各个领域之中。虽然现在深度学习相对于这些传统方法更为火热&#xff0c;但实…

基础算法(3):排序(3)插入排序

1.插入排序实现 插入排序的工作原理是&#xff1a;通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已经排序的序列从后向前扫描&#xff0c;找到位置并插入&#xff0c;类似于平时打扑克牌时&#xff0c;将牌从大到小排列&#xff0c;每次摸到一张牌就插入到正确的位…

12.4~12.14概率论复习与相应理解(学习、复习、备考概率论,这一篇就够了)

未分配的题目 概率计算&#xff08;一些转换公式与全概率公式&#xff09;与实际概率 &#xff0c;贝叶斯 一些转换公式 相关性质计算 常规&#xff0c;公式的COV与P 复习相关公式 计算出新表达式的均值&#xff0c;方差&#xff0c;再套正态分布的公式 COV的运算性质 如…

前后端项目,nginx部署前端项目后刷新浏览器报错404的问题

问题&#xff1a; Vue单页应用项目打包部署Nginx服务器后&#xff0c;刷新页面后&#xff0c;出现404。 原因&#xff1a; 加载单页应用后路由改变均由浏览器处理&#xff0c;而刷新时将会请求当前的链接&#xff0c;而Nginx无法找到对应的页面。 解决&#xff1a; 在Nginx配…

python爬虫学习-批量爬取图片

python爬虫学习-批量爬取图片 爬虫步骤爬取前十页图片到本地根据页码获取网络源码使用xpath解析网页解析网页并下载图片主函数如下 爬取的网站为站长素材&#xff08;仅做学习使用&#xff09; 爬取的目标网站为 https://sc.chinaz.com/tupian/qinglvtupian.html如果爬取多页&…

大数据讲课笔记1.2 Linux用户操作

文章目录 零、学习目标一、导入新课二、新课讲解&#xff08;一&#xff09;用户账号管理1、用户与用户组文件2、用户账号管理工作 &#xff08;二&#xff09;用户操作1、切换用户&#xff08;1&#xff09;语法格式&#xff08;2&#xff09;切换到普通用户&#xff08;3&…

NVH软件导入音频文件

我们经常会遇到一种情况是&#xff1a;车主上下班路上经常会听到一个异响&#xff0c;但车交到我们手上&#xff0c;我们怎么在外面去试车&#xff0c;都听不到这个异响&#xff0c;或者条件达不到重现不了这个异响。如果是这样&#xff0c;我们是不是有点崩溃&#xff1f;但&a…

jstree组件的使用详细教程,部分案例( PHP / fastAdmin )

jstree 组件的使用。 简介&#xff1a;JsTree是一个jquery的插件&#xff0c;它提交一个非常友好并且强大的交互性的树&#xff0c;并且是完全免费或开源的&#xff08;MIT 许可&#xff09;。Jstree技持Html 或 json格式的的数据&#xff0c; 或者是ajax方式的动态请求加载数…

公司团队规范研发流程概要

一、背景 ● 背景&#xff1a;XXX研发部门开发流程步骤以及开发工具&#xff0c;依赖版本&#xff0c;开发规范等相关信息。 ● 技术定位&#xff1a;All。 ● 目标群体&#xff1a;所有相关研发部门技术人员。 二、操作步骤 2.1 开发前的准备 准备工作一 开发相关账号开通…

中职网络安全应急响应—Server2228

应急响应 任务环境说明: 服务器场景:Server2228(开放链接) 用户名:root,密码:p@ssw0rd123 1. 找出被黑客修改的系统别名,并将倒数第二个别名作为Flag值提交; 通过用户名和密码登录系统 在 Linux 中,利用 “alias” 命令去查看当前系统中定义的所有别名 flag:ss …

软实力篇---第二篇

系列文章目录 文章目录 系列文章目录前言一、必知必会的几点二、必须了解的两大法则三、项目经历怎么写前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 一、必知必…