代码随想录 回溯算法-子集

news2024/10/25 6:23:43

目录

78.子集 

90.子集||

491.非递减子序列 


78.子集 

78. 子集

中等

给你一个整数数组 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 中的所有元素 互不相同

class Solution {  
    // 用于存放所有可能的子集结果  
    List<List<Integer>> result = new ArrayList<>();  
    // 用于存放当前正在构建的子集路径  
    List<Integer> path = new ArrayList<>();  
  
    // 主函数,用于获取输入数组的所有子集  
    public List<List<Integer>> subsets(int[] nums) {  
        // 从数组的第一个元素开始进行回溯  
        backtracking(nums, 0);  
        // 返回所有子集的结果  
        return result;  
    }  
  
    // 回溯函数,用于构建所有可能的子集  
    public void backtracking(int[] nums, int begin) {  
        // 将当前路径添加到结果集中,这里注意要创建一个新的ArrayList来避免后续修改影响到结果集  
        result.add(new ArrayList<>(path));  
  
        // 如果已经遍历到数组的末尾,则结束当前回溯路径  
        if (begin == nums.length) {  
            return;  
        }  
  
        // 从当前位置开始遍历数组,选择元素加入子集  
        for (int i = begin; i < nums.length; i++) {  
            // 将当前元素加入子集路径  
            path.add(nums[i]);  
            // 递归调用,继续构建下一个位置的子集  
            backtracking(nums, i + 1);  
            // 回溯,移除刚刚加入的子集路径中的元素,尝试其他可能性  
            path.removeLast();  
        }  
    }  
}

90.子集||

90. 子集 II

中等

给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的<span data-keyword="subset">子集</span>(幂集)。

解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。

示例 1:

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

示例 2:

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

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10

 注意这里也是树层去重

class Solution {  
    // 用于存放所有可能的子集结果  
    List<List<Integer>> result = new ArrayList<>();  
    // 用于存放当前正在构建的子集路径  
    List<Integer> path = new ArrayList<>();  
  
    // 主函数,用于获取输入数组的所有子集(包括重复元素)  
    public List<List<Integer>> subsetsWithDup(int[] nums) {  
        // 先对数组进行排序,这样相同的元素会相邻,便于去重  
        Arrays.sort(nums);  
        // 从数组的第一个元素开始进行回溯  
        backtracking(nums, 0);  
        // 返回所有子集的结果  
        return result;  
    }  
  
    // 回溯函数,用于构建所有可能的子集  
    public void backtracking(int[] nums, int begin) {  
        // 将当前路径添加到结果集中,注意要创建一个新的ArrayList来避免后续修改影响到结果集  
        result.add(new ArrayList<>(path));  
  
        // 如果已经遍历到数组的末尾,则结束当前回溯路径  
        if (begin == nums.length) {  
            return;  
        }  
  
        // 从当前位置开始遍历数组,选择元素加入子集  
        for (int i = begin; i < nums.length; i++) {  
            // 如果当前元素和前一个元素相同,并且不是从begin开始的第一个元素(即不是第一个出现的重复元素),则跳过,避免重复子集  
            if (i > begin && nums[i] == nums[i - 1]) {  
                continue;  
            }  
            // 将当前元素加入子集路径  
            path.add(nums[i]);  
            // 递归调用,继续构建下一个位置的子集  
            backtracking(nums, i + 1);  
            // 回溯,移除刚刚加入的子集路径中的元素,尝试其他可能性  
            path.removeLast();  
        }  
    }  
}

491.非递减子序列 

491. 非递减子序列

中等

给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。

数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。

示例 1:

输入:nums = [4,6,7,7]
输出:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]

示例 2:

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

提示:

  • 1 <= nums.length <= 15
  • -100 <= nums[i] <= 100

 看到这道题我的第一反应是

class Solution {  
    // 存储所有满足条件的递增子序列的结果集合  
    List<List<Integer>> result = new ArrayList<>();  
    // 用于构建当前递增子序列的临时路径  
    List<Integer> path = new ArrayList<>();  
  
    public List<List<Integer>> findSubsequences(int[] nums) {  
        // 调用回溯函数,从数组的第一个元素开始寻找递增子序列  
        backtracking(nums, 0);  
        // 返回所有满足条件的递增子序列  
        return result;  
    }  
  
    public void backtracking(int[] nums, int begin) {  
        // 如果当前路径中的元素个数大于等于2,则将路径添加到结果集合中  
        if (path.size() >= 2) {  
            result.add(new ArrayList<>(path));  
        }  
  
        // 如果已经遍历到数组的末尾,则回溯结束  
        if (begin == nums.length) {  
            return;  
        }  
  
        // 从begin位置开始遍历数组  
        for (int i = begin; i < nums.length; i++) {  
            // 如果当前元素与前一个元素相同且不是序列的第一个元素,则跳过以避免重复  
            if (i > begin && nums[i] == nums[i - 1]) {  
                continue;  
            }  
  
            // 如果当前路径为空,或者当前元素大于等于路径中的最后一个元素,则继续构建子序列  
            if (path.isEmpty() || nums[i] >= path.get(path.size() - 1)) {  
                // 将当前元素添加到路径中  
                path.add(nums[i]);  
                // 递归调用,继续构建子序列,从下一个元素开始  
                backtracking(nums, i + 1);  
                // 回溯,将当前元素从路径中移除,探索其他可能性  
                path.removeLast();  
            }  
        }  
    }  
}

后来发现这道题的原数组是不能排序的,会破坏结果,用数组或者map来去重,这里使用数组

同样是树层去重

class Solution {  
    // 结果集合,存储所有满足条件的递增子序列  
    List<List<Integer>> res = new ArrayList<>();  
    // 路径集合,用于构建当前递增子序列  
    LinkedList<Integer> path = new LinkedList<>();  
  
    public List<List<Integer>> findSubsequences(int[] nums) {  
        // 从数组的第一个元素开始,寻找所有递增子序列  
        backtracking(nums, 0);  
        // 返回所有满足条件的子序列  
        return res;  
    }  
  
    private void backtracking(int[] nums, int begin) {  
        // 如果当前路径中的元素数量大于1,则将其作为一个有效的递增子序列加入结果集  
        if (path.size() > 1) {  
            res.add(new ArrayList<>(path));  
            // 注意这里不要加return,要取树上的节点  
            // 不能在这里return,因为需要继续探索当前路径下可能的其他子序列  
        }  
          
        // 创建一个used数组来记录当前遍历过程中每个数字是否被使用过
        // 用于避免将重复数字添加到子序列中  
        int[] used = new int[201];
          
        // 从begin位置开始遍历数组  
        for (int i = begin; i < nums.length; i++) {  
            // 如果当前数字在本层遍历中已经被使用过,跳过防止重复  
            if (used[nums[i] + 100] == 1) {  
                continue;  
            }  
            // 如果当前路径为空,或者当前元素大于等于路径中的最后一个元素,则继续构建子序列  
            if (path.isEmpty() || nums[i] >= path.get(path.size() - 1)) { 
                //标记该数字被使用过
                used[nums[i] + 100] = 1; 
                // 将当前元素添加到路径中  
                path.add(nums[i]);  
                // 递归调用,继续构建子序列,从下一个元素开始  
                backtracking(nums, i + 1);  
                // 回溯,将当前元素从路径中移除,探索其他可能性  
                path.removeLast();  
            }  
        }  
    }  
}

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

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

相关文章

教程篇:Groq API+沉浸式翻译插件 体验最快AI翻译

1、进入https://console.groq.com/keys 申请一个API&#xff08;目前免费&#xff01;抓紧白嫖&#xff09; 2、安装Chrome插件&#xff1a;沉浸式翻译。 https://immersivetranslate.com/ 3、照着抄&#xff08;注意将apikey&#xff0c;换成自己申请的groq的api-key&…

算法刷题Day1 | 704.二分查找、27.移除元素

目录 0 引言1 二分查找1.1 我的解题1.2 修改后1.3 总结 2 移除元素2.1 暴力求解2.2 双指针法&#xff08;快慢指针&#xff09; &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;算法专栏&#x1f4a5; 标题&#xff1a;代码随想录算法训练营第一天…

什么是单点登录(SSO)前端用 iframe 实现单点登录 超详细说明!!

目录 什么是单点登录&#xff1f; 使用 iframe 实现单点登录 什么是单点登录&#xff1f; 单点登录的英文名叫做&#xff1a;Single Sign On&#xff08;简称SSO&#xff09;。 单点登录是一种身份验证过程&#xff0c;允许用户通过一次登录验证即可访问多个应用程序或服务…

达梦数据库基础操作(二):表空间操作

达梦数据库基础操作(二)&#xff1a;表空间操作 1. 表空间操作 1.1 达梦表空间介绍 表空间的概念&#xff1a; 每个DM 数据库都是由一个或者多个表空间组成&#xff0c;表空间是一个逻辑的存储容器&#xff0c;它位于逻辑结构的顶层&#xff0c;用于存储数据库中的所有数据&am…

ChatMASTER部署教程

项目简介 ChatMASTER&#xff0c;基于AI大模型api实现的自建后端Chat服务&#xff0c;支出同步响应及流式响应&#xff0c;完美呈现打印机效果。支持一键切换ChatGPT(3.5、4.0)模型、文心一言(支持Stable-Diffusion-XL作图)、通义千问、讯飞星火、智谱清言(ChatGLM)等主流模型…

《JAVA与模式》之迭代子模式

系列文章目录 文章目录 系列文章目录前言一、聚集和JAVA聚集二、迭代子模式的结构三、白箱聚集与外禀迭代子四、外禀迭代子的意义五、黑箱聚集与内禀迭代子 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给…

教育界杂志《教育界》杂志社教育界编辑部2024年第2期目录

教育视界 小学语文课内外阅读的有效融合策略 任小惠; 2-4 项目化学习在初中音乐教学中的应用探索 毛海蓉; 5-7 探索之窗《教育界》投稿&#xff1a;cn7kantougao163.com 儿童无边界阅读支撑系统的建构与实施 袁干斌;蒯红良; 8-10 中学教学 基于核心素养培养的高…

【Spring高级】第2讲:容器实现类

目录 BeanFactory实现BeanDefinition后置处理器单例bean创建后置处理器顺序总结 ApplicationContext实现ClassPathXmlApplicationContextFileSystemXmlApplicationContextAnnotationConfigApplicationContextAnnotationConfigServletWebServerApplicationContext BeanFactory实…

Lazada本土店与跨境店区别,附店铺防关联攻略

许多新手商家在初入跨境电商时&#xff0c;对于平台账号类别并不清楚。Lazada是最大的东南亚在线购物平台之一&#xff0c;如果你的跨境目标正指向东南亚&#xff0c;那么Lazada一定是是你的首选平台。那么接下来让小编带大家认识Lazada本土店与跨境店的区别&#xff01; 一、本…

DNS——域名系统

TCP/IP提供了通过IP地址来连接到设备的功能&#xff0c;但对用户来讲&#xff0c;记住某台设备的IP地址是相当困难的&#xff0c;因此专门设计了一种字符串形式的主机命名机制&#xff0c;这些主机名与IP地址相对应。在IP地址与主机名之间需要有一种转换和查询机制&#xff0c;…

基于springboot的某大学外卖系统的实现(源码+论文)

文章目录 目录 文章目录 前言 一、功能设计 二、功能实现 1 后台登录 2管理员界面 3员工信息管理 4客户信息管理 三、库表设计 四、论文 前言 如今&#xff0c;信息化不断的高速发展&#xff0c;社会也跟着不断进步&#xff0c;现今的社会&#xff0c;各种工作都离不开信息化技…

python 截取字符串string.split

目录 作用语法只要第一个值获得第3个值遍历 作用 根据某个符号对数据进行截取 从而获得自己想要的内容 语法 使用’string.split’ 方法 对字符串’123/abc/BPYC’ 以 ‘/’ 进行截取 string "123/abc/BPYC" substring string.split("/") print(subs…

亚马逊运营要使用什么海外代理IP?

代理IP作为网络活动的有力工具&#xff0c;同时也是跨境电商的必备神器。亚马逊作为跨境电商的头部平台&#xff0c;吸引了大量的跨境电商玩家入驻&#xff0c;想要做好亚马逊&#xff0c;养号、测评都需要代理IP的帮助。那么应该使用什么代理IP呢&#xff1f;如何使用&#xf…

【投稿优惠|火热征稿】2024年计算机技术与自动化发展国际会议 (ICCTAD 2024)

2024年计算机技术与自动化发展国际会议 (ICCTAD 2024) 2024 International Conference on Computer Technology and Automation Development (ICCTAD 2024) 【会议简介】 2024年计算机技术与自动化发展国际会议( ICCTAD 2024)将在中国武汉盛大开幕&#xff01;这是一场在自动化…

【AI视野·今日Sound 声学论文速览 第五十二期】Tue, 5 Mar 2024

AI视野今日CS.Sound 声学论文速览 Tue, 5 Mar 2024 Totally 18 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers SA-SOT: Speaker-Aware Serialized Output Training for Multi-Talker ASR Authors Zhiyun Fan, Linhao Dong, Jun Zhang, Lu Lu, Zejun M…

【海贼王的数据航海:利用数据结构成为数据海洋的霸主】栈和队列

目录 1 -> 栈 1.1 -> 栈的概念及结构 1.2 -> 栈的实现 1.2.1 -> Stack.h 1.2.2 -> Stack.c 1.2.3 -> Test.c 2 -> 队列 2.1 -> 队列的概念及结构 2.2 -> 队列的实现 2.2.1 -> Queue.h 2.2.2 -> Queue.c 1 -> 栈 1.1 -> 栈的…

如何在Linux系统Docker部署Dashy并远程访问内网服务界面

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Python算法题集_N 皇后

Python算法题集_N 皇后 题51&#xff1a;N 皇后1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【规则遍历合理性回溯】2) 改进版一【线状态检测合理性回溯】3) 改进版二【单行矩阵回溯】 4. 最优算法5. 相关资源 本文为Python算法题集之一的代码…

威步安全技术保护铁路免受网络威胁

IoW的TrainCAS列车碰撞预警系统保护铁路列车免受网络攻击。TrainCAS系统内置的高端技术及其被非法利用的风险&#xff0c;让安全和知识产权保护成为公司的首要任务。TrainCAS软件及其轨道图通过CodeMeter AxProtector和Core API工具的结合得到保护&#xff0c;有效防止未授权使…

任务调度新境界:探秘ScheduledExecutorService的异步魔力

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 任务调度新境界&#xff1a;探秘ScheduledExecutorService的异步魔力 前言ScheduledExecutorService的基本概念基本概念&#xff1a;为何它是 Java 中任务调度的首选工具&#xff1a;基本用法&#xf…