代码随想录-回溯算法

news2024/9/27 10:19:37

在这里插入图片描述

  1. 组合
//未剪枝
class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    Deque<Integer> path = new LinkedList<>();

    public List<List<Integer>> combine(int n, int k) {
        backtracking(n, k, 1);
        return ans;
    }

    public void backtracking(int n, int k, int startIndex) {
        if (path.size() == k) {
            ans.add(new ArrayList<>(path));
            return;
        }
        for (int i = startIndex; i <= n; i++) {
            path.add(i);
            backtracking(n, k, i + 1);
            path.removeLast();
        }
    }
}
//剪枝
class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    Deque<Integer> path = new LinkedList<>();

    public List<List<Integer>> combine(int n, int k) {
        backtracking(n, k, 1);
        return ans;
    }

    public void backtracking(int n, int k, int startIndex) {
        if (path.size() == k) {
            ans.add(new ArrayList<>(path));
            return;
        }
        for (int i = startIndex; i <= n - (k - path.size()) + 1; i++) {
            path.add(i);
            backtracking(n, k, i + 1);
            path.removeLast();
        }
    }
}
  1. 组合总和 III
class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    Deque<Integer> path = new LinkedList<>();

    public List<List<Integer>> combinationSum3(int k, int n) {
        backtracking(k, n, 0, 1);
        return ans;
    }

    public void backtracking(int k, int targetSum, int sum, int startIndex) {
        if (path.size() == k) {
            if (sum == targetSum) {
                ans.add(new ArrayList<>(path));
            }
            return;
        }
        for (int i = startIndex; i <= 9; i++) {
            sum += i;
            path.add(i);
            backtracking(k, targetSum, sum, i + 1);
            sum -= i;
            path.removeLast();
        }
    }
}
  1. 电话号码的字母组合
class Solution {
    List<String> ans = new ArrayList<>();

    StringBuilder temp = new StringBuilder();

    public List<String> letterCombinations(String digits) {
        if (digits == null || digits.length() == 0) {
            return ans;
        }
        String[] numString = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
        backTracking(digits, numString, 0);
        return ans;
    }

    public void backTracking(String digits, String[] numString, int len) {
        if (len == digits.length()) {
            ans.add(temp.toString());
            return;
        }
        String str = numString[digits.charAt(len) - '0'];
        for (int i = 0; i < str.length(); i++) {
            temp.append(str.charAt(i));
            backTracking(digits, numString, len + 1);
            temp.deleteCharAt(temp.length() - 1);
        }
    }
}
  1. 组合总和
//未剪枝
class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    Deque<Integer> path = new LinkedList<>();

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        bacaktracking(candidates, target, 0, 0);
        return ans;
    }

    public void bacaktracking(int[] candidates, int target, int sum, int startIndex) {
        if (sum > target) {
            return;
        }
        if (sum == target) {
            ans.add(new ArrayList<>(path));
            return;
        }
        for (int i = startIndex; i < candidates.length; i++) {
            sum += candidates[i];
            path.add(candidates[i]);
            bacaktracking(candidates, target, sum, i);
            sum -= candidates[i];
            path.removeLast();
        }
    }
}

在求和问题中,排序之后加剪枝是常见的套路!

//剪枝
class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    Deque<Integer> path = new LinkedList<>();

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates);
        bacaktracking(candidates, target, 0, 0);
        return ans;
    }

    public void bacaktracking(int[] candidates, int target, int sum, int startIndex) {
        if (sum == target) {
            ans.add(new ArrayList<>(path));
            return;
        }
        for (int i = startIndex; i < candidates.length; i++) {
            sum += candidates[i];
            if (sum > target) {
                break;
            }
            path.add(candidates[i]);
            bacaktracking(candidates, target, sum, i);
            sum -= candidates[i];
            path.removeLast();
        }
    }
}
  1. 组合总和 II
class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    Deque<Integer> path = new LinkedList<>();

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        backtracking(candidates, target, 0, 0);
        return ans;
    }

    public void backtracking(int[] candidates, int target, int sum, int startIndex) {
        if (sum == target) {
            ans.add(new ArrayList<>(path));
            return;
        }
        for (int i = startIndex; i < candidates.length; i++) {
            if (i > startIndex && candidates[i] == candidates[i - 1]) {
                continue;
            }
            sum += candidates[i];
            if (sum > target) {
                break;
            }
            path.add(candidates[i]);
            backtracking(candidates, target, sum, i + 1);
            sum -= candidates[i];
            path.removeLast();
        }
    }
}
  1. 分割回文串
class Solution {
    List<List<String>> ans = new ArrayList<>();
    Deque<String> path = new LinkedList<>();

    public List<List<String>> partition(String s) {
        backtracking(s, 0);
        return ans;
    }

    public void backtracking(String s, int startIndex) {
        if (startIndex >= s.length()) {
            ans.add(new ArrayList<>(path));
            return;
        }
        for (int i = startIndex; i < s.length(); i++) {
            if (isPalindrome(s, startIndex, i)) {
                String str = s.substring(startIndex, i + 1);
                path.add(str);
            } else {
                continue;
            }
            backtracking(s, i + 1);
            path.removeLast();
        }
    }

    public boolean isPalindrome(String s, int start, int end) {
        for (int i = startIndex, j = end; i < j; i++, j--) {
            if (s.charAt(i) != s.charAt(j)) {
                return false;
            }
        }
        return true;
    }
}
  1. 复原 IP 地址
class Solution {
    List<String> ans = new ArrayList<>();
    StringBuilder currentIP = new StringBuilder();

    public List<String> restoreIpAddresses(String s) {
        if (s.length() > 12)
            return ans;
        backtracking(s, 0, 0);
        return ans;
    }

    private void backtracking(String s, int startIndex, int pointNum) {
        if (pointNum == 3) {
            if (isValid(s, startIndex, s.length() - 1)) {
                currentIP.append(s.substring(startIndex));
                ans.add(currentIP.toString());

            }
            return;
        }
        for (int i = startIndex; i < s.length(); i++) {
            if (isValid(s, startIndex, i)) {
                int len = currentIP.length();
                currentIP.append(s.substring(startIndex, i + 1));
                if (pointNum < 3) {
                    currentIP.append(".");
                }
                backtracking(s, i + 1, pointNum + 1);
                currentIP.setLength(len);
            } else {
                break;
            }
        }
    }

    private Boolean isValid(String s, int start, int end) {
        if (start > end) {
            return false;
        }
        if (s.charAt(start) == '0' && start != end) { // 0开头的数字不合法
            return false;
        }
        int num = 0;
        for (int i = start; i <= end; i++) {
            if (s.charAt(i) > '9' || s.charAt(i) < '0') { // 遇到非数字字符不合法
                return false;
            }
            num = num * 10 + (s.charAt(i) - '0');
            if (num > 255) { // 如果大于255了不合法
                return false;
            }
        }
        return true;
    }
}
class Solution {
    List<String> ans = new ArrayList<>();
    StringBuilder currentIP = new StringBuilder();

    public List<String> restoreIpAddresses(String s) {
        if (s.length() > 12)
            return ans;
        backtracking(s, 0, 0);
        return ans;
    }

    private void backtracking(String s, int startIndex, int pointNum) {
        if (pointNum == 3) {
            if (isValid(s, startIndex, s.length() - 1)) {
                currentIP.append(s.substring(startIndex));
                ans.add(currentIP.toString());

            }
            return;
        }
        for (int i = startIndex; i < s.length(); i++) {
            if (isValid(s, startIndex, i)) {
                int len = currentIP.length();
                currentIP.append(s.substring(startIndex, i + 1));
                if (pointNum < 3) {
                    currentIP.append(".");
                }
                backtracking(s, i + 1, pointNum + 1);
                currentIP.setLength(len);
            } else {
                break;
            }
        }
    }

    private Boolean isValid(String s, int start, int end) {
        if (start > end) {
            return false;
        }
        if (s.charAt(start) == '0' && start != end) {
            return false;
        }
        if (Integer.parseInt(s.substring(start, end + 1)) < 0 || Integer.parseInt(s.substring(start, end + 1)) > 255) {
            return false;
        }
        return true;
    }
}
  1. 子集
class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    Deque<Integer> path = new LinkedList<>();

    public List<List<Integer>> subsets(int[] nums) {
        backtracking(nums, 0);
        return ans;
    }

    public void backtracking(int[] nums, int startIndex) {
        ans.add(new ArrayList<>(path));
        if (startIndex >= nums.length) {
            return;
        }
        for (int i = startIndex; i < nums.length; i++) {
            path.add(nums[i]);
            backtracking(nums, i + 1);
            path.removeLast();
        }
    }

}
  1. 子集 II
class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    Deque<Integer> path = new LinkedList<>();

    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
        backtracking(nums, 0);
        return ans;
    }

    public void backtracking(int[] nums, int startIndex) {
        ans.add(new ArrayList<>(path));

        for (int i = startIndex; i < nums.length; i++) {
            if (i > startIndex && nums[i - 1] == nums[i]) {
                continue;
            }
            path.add(nums[i]);
            backtracking(nums, i + 1);
            path.removeLast();
        }
    }
}
  1. 非递减子序列
class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    Deque<Integer> path = new LinkedList<>();

    public List<List<Integer>> findSubsequences(int[] nums) {
        backtacking(nums, 0);
        return ans;
    }

    public void backtacking(int[] nums, int startIndex) {
        if (path.size() >= 2) {
            ans.add(new ArrayList<>(path));
        }
        Set<Integer> set = new HashSet<>();
        for (int i = startIndex; i < nums.length; i++) {
            if (!path.isEmpty() && path.peekLast() > nums[i] || set.contains(nums[i])) {
                continue;
            }
            set.add(nums[i]);
            path.add(nums[i]);
            backtacking(nums, i + 1);
            path.removeLast();
        }
    }
}
  1. 全排列
class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    Deque<Integer> path = new LinkedList<>();

    public List<List<Integer>> permute(int[] nums) {
        if (nums.length == 0) {
            return ans;
        }
        backtracking(nums, path);
        return ans;
    }

    public void backtracking(int[] nums, Deque<Integer> path) {
        if (path.size() == nums.length) {
            ans.add(new ArrayList<>(path));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (path.contains(nums[i])) {
                continue;
            }
            path.add(nums[i]);
            backtracking(nums, path);
            path.removeLast();
        }
    }
}

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

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

相关文章

js中浏览器渲染原理

JavaScript&#xff08;JS&#xff09;是一种广泛使用的编程语言&#xff0c;特别是在Web开发中。在浏览器中&#xff0c;JS被用于实现动态网页效果、交互性和用户体验的提升。然而&#xff0c;要理解JS在浏览器中的工作原理&#xff0c;我们首先需要了解浏览器的渲染过程。 浏…

C++之函数,指针

函数 1&#xff0c;函数概述 作用&#xff1a;将一段经常使用的代码封装起来&#xff0c;减少重复代码 一个较大的程序&#xff0c;一般分为若干份程序块&#xff0c;每个模块实现特定的功能 2&#xff0c;函数的定义 函数的定义一般有五个步骤&#xff1a; 1&#xff0c…

【前端素材】推荐优质数医院办公后台管理系统网页Stisla平台模板(附源码)

一、需求分析 在线后台管理系统是指供管理员或运营人员使用的Web应用程序&#xff0c;用于管理和监控网站、应用程序或系统的运行和数据。它通常包括一系列工具和功能&#xff0c;用于管理用户、内容、权限、数据等。下面是关于在线后台管理系统的详细分析&#xff1a; 1、功…

​用细节去解释,如何打造一款行政旗舰车型

高山行政加长版应该是这个级别里最大的几款 MPV 之一了&#xff0c;对于一款较大的车型&#xff0c;其最重要的是解决行驶的便利性。 这次我们就试试魏牌高山行政加长版&#xff0c;从产品本身出发看几个纬度的细节&#xff1a; 行政该如何定义加长后产品的功能变化加长之后到…

ssm172旅行社管理系统的设计与实现

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一 、设计说明 1.1 研究…

深入浅出Redis(零):Redis常用命令的使用

前言 Redis是一款基于键值对的数据结构存储系统&#xff0c;它的特点是基于内存操作、单线程处理命令、IO多路复用模型处理网络请求、键值对存储与简单丰富的数据结构等等 本篇文章作为深入浅出Redis&#xff08;一&#xff09;&#xff1a;对象与数据结构的基础篇&#xff0…

docker自定义镜像与上传

alpine制作jdk镜像 alpine Linux简介 1.Alpine Linux是一个轻型Linux发行版&#xff0c;它不同于通常的Linux发行版&#xff0c;Alpine采用了musl libc 和 BusyBox以减少系统的体积和运行时的资源消耗。 2.Alpine Linux提供了自己的包管理工具&#xff1a;apk(注意&#xff1a;…

修改docker默认存储位置【高版本的docker】

一、修改docker默认存储位置 1、停服务 systemctl stop docker 2、修改/etc/docker/daemon.json添加新的dcoker路径 如"data-root": "/mnt/hdd1/docker" 3、保存后重启服务&#xff1a;systemctl restart docker 二、其他服务的命令 systemctl disab…

4.1.CVAT——目标检测的标注详细步骤

文章目录 1. 进入任务1. 创建任务2. 已创建的task3. 进入标注界面 2. 选择标注类型2.1 选择标注类型2.2 进行标注2.3 遮挡 2.快捷键3.导出标注结果 1. 进入任务 登录后会看到如下图界面&#xff0c;CVAT的标注最小单位是Task&#xff0c;每个Task为一个标注任务。点击Task按钮…

python实现ElGamal算法

ElGamal公钥密码算法是在密码协议中有着重要应用的一类公钥密码算法&#xff0c;基于公钥密码体制和椭圆曲线加密体系&#xff0c;其安全性是基于有限域上离散对数学问题的难解性。至今仍是一个安全性良好的公钥密码算法。既可用于加密又可用于数字签名的公钥密码体制。 数字签…

浅谈人才招聘APP开发的解决方案

随着企业竞争加剧&#xff0c;高效、精准地招聘人才成为企业持续发展的关键。人才招聘系统能够简化招聘流程&#xff0c;提高效率&#xff0c;确保企业快速找到合适人才。同时&#xff0c;通过智能匹配和数据分析&#xff0c;提升招聘质量&#xff0c;优化候选人体验。因此&…

【Vue3】自定义 Vue3 插件(全局实现页面加载动画)

// main.ts import { createApp } from vue import App from ./App.vue import Loading from "./components/Loading/index.ts";const app createApp(App) type Lod {show: () > void,hide: () > void } //编写ts loading 声明文件放置报错 和 智能提示 decl…

腾讯云优惠券领取的三个渠道,一个比一个优惠!

腾讯云代金券领取渠道有哪些&#xff1f;腾讯云官网可以领取、官方媒体账号可以领取代金券、完成任务可以领取代金券&#xff0c;大家也可以在腾讯云百科蹲守代金券&#xff0c;因为腾讯云代金券领取渠道比较分散&#xff0c;腾讯云百科txybk.com专注汇总优惠代金券领取页面&am…

MyBatis 学习(四)之 SQL 映射文件

目录 1 SQL 映射文件介绍 2 select 元素 3 insert 元素 4 update 和 delete 元素 5 sql 元素 6 parameterType 元素 7 resultType 元素 8 resultMap 元素&#xff08;重要&#xff09; 9 参考文档 1 SQL 映射文件介绍 映射器是 MyBatis 中最复杂并且是最重要的…

Vue开发实例(二)Vue代码运行及分析配置

Vue项目代码运行及分析 一、项目运行二、目录结构说明1、项目本身结构2、其他可能用到的文件夹 三、建议配置1、启动服务浏览器自动打开页面地址2、关闭eslint校验工具3、 src文件夹的别名的设置 一、项目运行 上篇文件末尾介绍到&#xff0c;进入项目&#xff0c;运行启动命令…

Unity(第二十二部)官方的反向动力学一般使用商城的IK插件,这个用的不多

反向动力学&#xff08;Inverse Kinematic&#xff0c;简称IK&#xff09;是一种通过子节点带动父节点运动的方法。 正向动力学 在骨骼动画中&#xff0c;大多数动画是通过将骨架中的关节角度旋转到预定值来生成的&#xff0c;子关节的位置根据父关节的旋转而改变&#xff0c;这…

【LeetCode】【滑动窗口长度不固定】978 最长湍流子数组

1794.【软件认证】最长的指定瑕疵度的元音子串 这个例题&#xff0c;是滑动窗口中长度不定求最大的题目&#xff0c;在看题之前可以先看一下【leetcode每日一题】【滑动窗口长度不固定】案例。 题目描述 定义&#xff1a;开头和结尾都是元音字母&#xff08;aeiouAEIOU&…

java基础-mysql

文章目录 mysql基础面试题什么是mysql什么是事务并发事务带来的影响事物的隔离级别索引大表优化什么是池化思想&#xff0c;什么是数据库连接池&#xff0c;为什么要用数据库连接池⾏锁&#xff0c;表锁&#xff1b;乐观锁&#xff0c;悲观锁MySQL主备同步的基本原理SQL什么情况…

2024年腾讯云优惠代金券领取入口汇总(新老用户免费领)

腾讯云代金券领取渠道有哪些&#xff1f;腾讯云官网可以领取、官方媒体账号可以领取代金券、完成任务可以领取代金券&#xff0c;大家也可以在腾讯云百科蹲守代金券&#xff0c;因为腾讯云代金券领取渠道比较分散&#xff0c;腾讯云百科txybk.com专注汇总优惠代金券领取页面&am…

基于 STM32U5 片内温度传感器正确测算温度

目录预览 1、引言 2、问题 3、小结 01 引言 STM32 在内部都集成了一个温度传感器&#xff0c;STM32U5 也不例外。这个位于晶圆上的温度传感器虽然不太适合用来测量外部环境的温度&#xff0c;但是用于监控晶圆上的温度还是挺好的&#xff0c;以防止芯片过温运行。 02 问题…