【算法练习】leetcode算法题合集之回溯篇

组合问题

LeetCode39: 组合总和

LeetCode39. 组合总和

目标和,除了累加所有的数外还可以用目标值减去所有的数。

添加第i个元素后,可以继续添加第i个元素。可以添加第i个元素,也可以添加索引为candidates.length-1的元素

这类回溯的问题可以想象成多叉数,对于根节点有左右子树,对于组合而言,多叉树的集合是candidates的所有的元素。以及考虑所有子元素的下一层的子元素集合是什么。

class Solution {List<List<Integer>> res = new ArrayList<>();LinkedList<Integer> path = new LinkedList<>();public List<List<Integer>> combinationSum(int[] candidates, int target) {backtrack(candidates, target, 0);return res;}private void backtrack(int[] candidates, int target, int idx) {if (target == 0) {res.add(new ArrayList<>(path));}if (target < 0 || idx == candidates.length) {return;}for (int i = idx; i < candidates.length; i++) {path.add(candidates[i]);backtrack(candidates, target - candidates[i], i );path.pollLast();}}
}

LeetCode40: 组合总和II

LeetCode40: 组合总和II

每个数字只能使用一次,并不意味着不允许重复元素。如果原数组中存在两个1,和是2,是可以有[1,1]的组合

进入下一次递归的时候,需要进行索引加1,当前元素不能再用。

i > idx && candidates[i] == candidates[i - 1],目的是防止数组中有两个1,第一个1和第二个1在与其他元素搭配的时候作用是一样的,需要过滤。因此,数组必须是有序的,保证相等的元素相邻。

class Solution {List<List<Integer>> res = new ArrayList<>();LinkedList<Integer> path = new LinkedList<>();public List<List<Integer>> combinationSum2(int[] candidates, int target) {Arrays.sort(candidates);backtrack(candidates, target, 0);return res;}private void backtrack(int[] candidates, int target, int idx) {if (target == 0) {res.add(new ArrayList<>(path));}if (target < 0) {return;}for (int i = idx; i < candidates.length; i++) {if (i > idx && candidates[i] == candidates[i - 1]) {continue;}path.add(candidates[i]);backtrack(candidates, target - candidates[i], i + 1);path.pollLast();}}}

LeetCode17. 电话号码的字母组合

LeetCode17. 电话号码的字母组合

当长度相等满足,则加入结果集

字符’2’转为数字2,digits.charAt(idx) - '0'

class Solution {List<String> res = new ArrayList<>();StringBuilder sb = new StringBuilder();String[] numString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};public List<String> letterCombinations(String digits) {if (digits == null || digits.length() == 0) {return res;}dfs(digits, 0);return res;}private void dfs(String digits, int idx) {if (sb.length() == digits.length()) {res.add(sb.toString());return;}String str = numString[digits.charAt(idx) - '0'];for (int i = 0; i < str.length(); i++) {sb.append(str.charAt(i));dfs(digits, idx + 1);sb.deleteCharAt(sb.length() - 1);}}
}

子集问题

LeetCode78:子集

LeetCode78. 子集

startIndex == nums.length这个校验可有可无。

子集第一层子集合是[0,nums.length-1],对于选择0的元素,下一层的子集合是[1,nums.length-1]

class Solution {List<List<Integer>> res = new ArrayList<>();LinkedList<Integer> path = new LinkedList<>();public List<List<Integer>> subsets(int[] nums) {dfs(nums, 0);return res;}private void dfs(int[] nums, int idx) {res.add(new ArrayList<>(path));if (startIndex == nums.length) {return;}for (int i = idx; i < nums.length; i++) {path.add(nums[i]);dfs(nums, i + 1);path.pollLast();}}
}

LeetCode90:子集II

LeetCode90:子集II

i > idx && nums[i] == nums[i - 1]可以理解为同一层元素不能重复。i==idx的时候,i是第一个元素。

需要对数组进行排序,排序好的数组元素相等的在一起。

class Solution {List<List<Integer>> res = new ArrayList<>();LinkedList<Integer> path = new LinkedList<>();public List<List<Integer>> subsetsWithDup(int[] nums) {Arrays.sort(nums);dfs(nums, 0);return res;}private void dfs(int[] nums, int idx) {res.add(new ArrayList<>(path));for (int i = idx; i < nums.length; i++) {if (i > idx && nums[i] == nums[i - 1]) {continue;}path.add(nums[i]);dfs(nums, i + 1);path.pollLast();}}
}

LeetCode491: 非递减子序列

LeetCode491: 非递减子序列

子序列就是不能改变数组中的元素。

去重:使用boolean数组或者HashMap

递增的判断是获取path中最后一个元素和当前元素比较。

class Solution {List<List<Integer>> res = new ArrayList<>();LinkedList<Integer> path = new LinkedList<>();public List<List<Integer>> findSubsequences(int[] nums) {dfs(nums, 0);return res;}private void dfs(int[] nums, int idx) {if (path.size() > 1) {res.add(new ArrayList<>(path));}if (idx == nums.length) {return;}boolean[] used = new boolean[201];for (int i = idx; i < nums.length; i++) {if (used[nums[i] + 100] || (!path.isEmpty() && path.peekLast() > nums[i])) {continue;}path.add(nums[i]);used[nums[i]+ 100] = true;dfs(nums, i + 1);path.pollLast();}}
}

全排列问题

LeetCode46. 全排列

LeetCode46. 全排列

第一层集合是[0,nums.length-1],第二层集合是[0,nums.length-1]再减去第一层用的元素。

class Solution {List<List<Integer>> res = new ArrayList<>();LinkedList<Integer> path = new LinkedList<>();boolean[] used;public List<List<Integer>> permute(int[] nums) {used = new boolean[nums.length];dfs(nums);return res;}private void dfs(int[] nums) {if (path.size() == nums.length) {res.add(new ArrayList<>(path));return;}for (int i = 0; i < nums.length; i++) {if (used[i]) {continue;}path.add(nums[i]);used[i] = true;dfs(nums);used[i] = false;path.removeLast();}}
}

LeetCode47: 全排列II

LeetCode47: 全排列II

不能有重复的组合

i > 0 && nums[i] == nums[i - 1] && !vis[i - 1]。连续三个1,第一层使用第一个1,第二层使用第二个1(used[i-1]==true)。等于是1(a),1(b),1(c)只能有一个顺序。

class Solution {List<List<Integer>> result = new ArrayList<>();LinkedList<Integer> path = new LinkedList<>();boolean[] used;public List<List<Integer>> permuteUnique(int[] nums) {Arrays.sort(nums);used = new boolean[nums.length];dfs(nums);return result;}private void dfs(int[] nums) {if (nums.length == path.size()) {result.add(new ArrayList<>(path));return;}for (int i = 0; i < nums.length; i++) {if (used[i] || (i > 0 && nums[i] == nums[i - 1]) && !used[i - 1]) {continue;}path.add(nums[i]);used[i] = true;dfs(nums);used[i] = false;path.pollLast();}}
}

切割问题

LeetCode93: 复原IP地址(**)

LeetCode93: 复原IP地址

判断某字符串是否为合法字符串,大于等于0,小于等于255的字符串。

要切分为合理的4段,记录start为字符串的起始字符。当符合要求的时候,start == s.length() && split == 4

子树集合,[start,start + 2],只有3个位置可选。

题目的难点,需要把应用题理解为可以做回溯的题目。

class Solution {List<String> res = new ArrayList<>();LinkedList<String> path = new LinkedList<>();public List<String> restoreIpAddresses(String s) {dfs(s, 0, 0);return res;}private void dfs(String s, int start, int split) {if (start == s.length() && split == 4) {res.add(String.join(".", path));return;}for (int i = start; i < start + 3; i++) {if (i >= s.length()) {break;}if ((4 - split) * 3 < s.length() - i) {continue;}if (isValid(s, start, i)) {path.add(s.substring(start, i + 1));dfs(s, i + 1, split + 1);path.removeLast();}}}private boolean isValid(String s, int start, int end) {if (start != end && s.charAt(start) == '0') {return false;}int res = 0;for (int i = start; i <= end; i++) {res = res * 10 + (s.charAt(i) - '0');}return res >= 0 && res <= 255;}
}

网格类问题

LeetCode200: 岛屿数量

LeetCode200: 岛屿数量

回溯方法:计数,如果当前点为岛屿,将附近的土地置为0,避免重复计数。

class Solution {public int numIslands(char[][] grid) {if (grid == null || grid.length == 0 || grid[0].length == 0) {return 0;}int count = 0;int m = grid.length; //行的个数int n = grid[0].length; // 列的个数for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == '1') {count++;dfs(grid, i, j);}}}return count;}private void dfs(char[][] grid, int i, int j) {if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == '0') {return;}grid[i][j] = '0';dfs(grid, i - 1, j);dfs(grid, i + 1, j);dfs(grid, i, j - 1);dfs(grid, i, j + 1);}
}

LeetCode695: 岛屿的最大面积

LeetCode695: 岛屿的最大面积

class Solution {public int maxAreaOfIsland(int[][] grid) {if (grid == null || grid.length == 0 || grid[0].length == 0) {return 0;}int m = grid.length;int n = grid[0].length;int ans = 0;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == 1) {ans = Math.max(ans, dfs(grid, i, j));}}}return ans;}private int dfs(int[][] grid, int i, int j) {int res = 1;if (i >= grid.length || i < 0 || j < 0 || j >= grid[0].length || grid[i][j] == 0) {return 0;}grid[i][j] = 0;res += dfs(grid, i - 1, j);res += dfs(grid, i + 1, j);res += dfs(grid, i, j - 1);res += dfs(grid, i, j + 1);return res;}
}

LeetCode79. 单词搜索

LeetCode79. 单词搜索

board[i][j] == '.'设置为该点位已经使用过。

比较索引为index的元素,判断是否相等,相等则继续,不等则返回结果false。比较前后左右的结果。当索引为最后一个元素,判断为相等,则返回结果。

class Solution {public boolean exist(char[][] board, String word) {int m = board.length;int n = board[0].length;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (dfs(board, word, 0, i, j)) {return true;}}}return false;}private boolean dfs(char[][] board, String word, int index, int i, int j) {if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || word.charAt(index) != board[i][j]|| board[i][j] == '.') {return false;}if (index == word.length() - 1) {return true;}char tmp = board[i][j];board[i][j] = '.';boolean b = dfs(board, word, index + 1, i + 1, j)|| dfs(board, word, index + 1, i - 1, j)|| dfs(board, word, index + 1, i, j + 1)|| dfs(board, word, index + 1, i, j - 1);board[i][j] = tmp;return b;}
}

LeetCode207. N皇后

51. N 皇后

定义一个n*n的数组,插入所有的网格 .

校验新增的元素是否合理(竖向比较,45度比较,横向比较,135度比较)

将当前board保存到List<String>中,加入结果集

class Solution {List<List<String>> res = new ArrayList<>();public List<List<String>> solveNQueens(int n) {char[][] board = new char[n][n];for (int i = 0; i < board.length; i++) {Arrays.fill(board[i], '.');}dfs(board, 0, n);return res;}private void dfs(char[][] board, int index, int n) {if (index == n) {res.add(toArray(board));return;}for (int i = 0; i < board[index].length; i++) {if (isValid(board, index, i, n)) {board[index][i] = 'Q';dfs(board, index + 1, n);board[index][i] = '.';}}}private boolean isValid(char[][] board, int row, int col, int n) {for (int i = 0; i < row; i++) {if (board[i][col] == 'Q') {return false;}}for (int i = 0; i < col; i++) {if (board[row][i] == 'Q') {return false;}}for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {if (board[i][j] == 'Q') {return false;}}for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {if (board[i][j] == 'Q') {return false;}}return true;}public List<String> toArray(char[][] board) {List<String> list = new ArrayList<>();for (int i = 0; i < board.length; i++) {list.add(new String(board[i]));}return list;}
}

括号问题

LeetCode22. 括号生成

LeetCode22. 括号生成

这条题目我看到想过并且看答案已经不止3次了,每次看都像看新的题目一样,感觉很熟悉,就是不会做。

记录左括号的次数和右括号的次数,当左括号的次数和右括号的次数都等于n,满足条件。当左括号的次数小于右括号的次数,进行剪枝,比如())

class Solution {List<String> res = new ArrayList<>();public List<String> generateParenthesis(int n) {dfs(0, 0, n, "");return res;}private void dfs(int left, int right, int n, String s) {if (left == n && right == n) {res.add(s);return;}if (left < right) {return;}if (left < n) {dfs(left + 1, right, n, s + "(");}if (right < n) {dfs(left, right + 1, n, s + ")");}}
}

图问题

LeetCode207. 课程表

LeetCode207. 课程表

记录每个课程的先学课程数量,没有先学课程的加入队列。

记录边,边是[先学,后学]

class Solution {public boolean canFinish(int numCourses, int[][] prerequisites) {int[] indegree = new int[numCourses];List<List<Integer>> edges = new ArrayList<>();for (int i = 0; i < numCourses; i++) {edges.add(new ArrayList<>());}for (int[] prereq : prerequisites) {indegree[prereq[0]]++; // 入度,[1,2] 先学2再学1edges.get(prereq[1]).add(prereq[0]);}Queue<Integer> queue = new LinkedList<>();for (int i = 0; i < indegree.length; i++) {if (indegree[i] == 0) {queue.add(i);}}while (!queue.isEmpty()) {int poll = queue.poll();numCourses--;for (Integer pre : edges.get(poll)) {indegree[pre]--;if (indegree[pre] == 0) {queue.add(pre);}}}return numCourses == 0;}
}

在这里插入图片描述

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

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

相关文章

CHS_01.1.3.1+操作系统的运行机制

CHS_01.1.3.1操作系统的运行机制 操作系统的运行机制 也就是说 操作系统在计算机上是怎么运行的这样一个问题 操作系统的运行机制 也就是说 操作系统在计算机上是怎么运行的这样一个问题 那这个小节中会涉及到这样的一些概念 我们会学习到两种类型的指令 然后两种处理机状态和两…

【软件测试】刚入行的测试人,“我“该怎么提升自己技术能力...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 一个问题&#xf…

【Helm 及 Chart 快速入门】03、Chart 基本介绍

目录 一、Chart 基本介绍 1.1 什么是 Chart 1.2 Chart ⽬录结构 1.3 Chart.yaml ⽂件 二、创建不可配置 Chart 2.1 创建 Chart 2.2 安装 Chart 三、创建可配置的 Chart 3.1 修改 chart 3.2 安装 Chart 一、Chart 基本介绍 1.1 什么是 Chart Helm 部署的应…

LORA的基本原理

本文将介绍如下内容&#xff1a; 什么是Lora高效微调的基本原理LORA的实现方式LORA为何有效&#xff1f; 一、什么是LoRA LoRA 通常是指低秩分解&#xff08;Low-Rank Decomposition&#xff09;算法&#xff0c;是一种低资源微调大模型方法&#xff0c;论文如下: LoRA: Low…

大厂都在用的监控高可用方案,小公司还不赶紧学起来?

有一次在一家国企时&#xff0c;他们是使用的dockernginx做为自己的“云”。同时&#xff0c;监控告警平台也不完善&#xff0c;虽然使用的是PrometheusGrafana&#xff0c;但仅仅是用来“看大屏”。 同时所有的报警都是一个一个的脚本去写的&#xff0c;例如写一个python脚本…

卢森堡市场开发攻略,带你走进全球最富有的国家

卢森堡位于西欧&#xff0c;位于欧洲的十字路口&#xff0c;地理位置非常重要。卢森堡是高度发达的资本主义国家&#xff0c;人均gdp全球最高&#xff0c;是当之无愧的全球最富国家。卢森堡对外开放度高&#xff0c;很多产品依赖进口&#xff0c;也是一个非常不错的市场&#x…

医疗门诊诊所预约挂号视频问诊小程序开发

医疗门诊诊所预约挂号视频问诊小程序开发 医疗门诊诊所预约挂号视频问诊小程序开发 用户注册、登录&#xff1a;用户通过手机号注册、登录小程序账号&#xff0c;校验用户身份信息。预约挂号&#xff1a;用户选择就诊科室、日期和时间&#xff0c;预约医生门诊&#xff0c;并…

【OpenCV学习笔记06】- 制作使用轨迹条控制的调色板

这是对于 OpenCV 官方文档的 GUI 功能的学习笔记。学习笔记中会记录官方给出的例子&#xff0c;也会给出自己根据官方的例子完成的更改代码&#xff0c;同样彩蛋的实现也会结合多个知识点一起实现一些小功能&#xff0c;来帮助我们对学会的知识点进行结合应用。 如果有喜欢我笔…

简单易懂的PyTorch线性层解析:神经网络的构建基石

目录 torch.nn子模块Linear Layers详解 nn.Identity Identity 类描述 Identity 类的功能和作用 Identity 类的参数 形状 示例代码 nn.Linear Linear 类描述 Linear 类的功能和作用 Linear 类的参数 形状 变量 示例代码 nn.Bilinear Bilinear 类的功能和作用 B…

申请Certum IP证书的方法

Certum是波兰的一家数字证书颁发机构&#xff0c;可以为只有公网IP地址的网站提供IP证书的申请服务&#xff0c;为网站传输信息进行加密&#xff0c;提高网站SEO排名。Certum旗下的IP证书产品不多&#xff0c;其中比较受欢迎的就是DV基础型IP证书。今天就随SSL盾小编了解Certum…

社交通证经济学:Web3时代的社交奖励系统

Web3时代的到来带来了区块链技术和去中心化的新范式&#xff0c;社交媒体也在这场变革中经历着深刻的改变。 社交通证经济学作为Web3时代社交媒体的创新实践&#xff0c;重新定义了用户在平台上的价值和奖励体系。本文将深入探讨Web3时代社交通证经济学的背景、工作原理以及对…

最新版docker-compose安装

Ubuntu/Kali 下载安装最新版 docker-compose # FastGit加速 sudo curl -L "https://hub.fgit.cf/docker/compose/releases/download$(curl -L -i -s -o /dev/null -w "%{url_effective}\n" https://hub.fgit.cf/docker/compose/releases/latest | awk -F tag …

2024新年烟花代码完整版

文章目录 前言烟花效果展示使用教程查看源码HTML代码CSS代码JavaScript 新年祝福 前言 在这个充满希望和激动的2024年&#xff0c;新的一年即将拉开帷幕&#xff0c;而数字科技的创新与发展也如火如荼。烟花绚丽多彩的绽放&#xff0c;一直以来都是新年庆典中不可或缺的元素。…

学会这13个 Git 命令就够了!

提到版本控制工具Git&#xff0c;相信很多开发者都知道&#xff0c;其实我们在99%的日常时间里&#xff0c;只需要学会以下13个git命令就行了&#xff0c;让我们来一起看看吧&#xff01; 1、git init 这个命令是初始化一个新的Git仓库&#xff0c;即在当前目录中创建一个名为…

为什么伦敦金交易应该使用4小时以上的周期?

做伦敦金前&#xff0c;要先对市场走势进行分析。而分析市场总是涉及时间周期等问题&#xff0c;这也是投资者们存在疑惑的地方。到底我们需要选择什么时间周期呢&#xff1f;各人有个人的看法&#xff0c;而其中一种意见是&#xff0c;我们不应该使用低于4小时的周期&#xff…

【方差分析原理简介】

文章目录 方差分析&#xff08;Analysis of Variance&#xff0c;简称ANOVA&#xff09;1 方差分析流程2 借助sklean进行基于方差分析的特征筛选3 总结 方差分析&#xff08;Analysis of Variance&#xff0c;简称ANOVA&#xff09; 卡方检验更多的会考虑在衡量两个离散变量是…

【Java技术专题】「攻破技术盲区」攻破Java技术盲点之unsafe类的使用指南(打破Java的安全管控— sun.misc.unsafe)

Java后门机制 — sun.misc.unsafe 打破Java的安全管控关于Unsafe的编程建议实例化Unsafe后门对象使用sun.misc.Unsafe创建实例单例模式处理实现浅克隆&#xff08;直接获取内存的方式&#xff09;直接使用copyMemory原理分析 密码安全使用Unsafe类—示例代码 运行时动态创建类超…

敦煌网、国际站自养号测评:店铺销售怎么提高?

随着互联网的快速发展&#xff0c;电子商务成为了现代商业的重要组成部分。在众多电商平台中&#xff0c;敦煌网作为中国文化艺术产品的专业电商平台&#xff0c;吸引了大量消费者的关注。然而&#xff0c;如何提高敦煌网的销售业绩&#xff0c;成为了商家们共同面临的挑战。 …

diffusers加速文生图速度;stable-diffusion、PixArt-α

参考: https://pytorch.org/blog/accelerating-generative-ai-3/ https://colab.research.google.com/drive/1jZ5UZXk7tcpTfVwnX33dDuefNMcnW9ME?usp=sharing#scrollTo=jueYhY5YMe22 大概GPU资源8G-16G;另外模型资源下载慢可以在国内镜像:https://aifasthub.com/ 1、加速…

查看Linux磁盘空间

(1)、该命令会列出当前系统所有挂载的文件系统以及它们的使用情况&#xff0c;包括总容量、已用空间、可用空间、使用百分比等信息 df -h如果查看某一个文件夹的,可以 df -h folderName (2)、计算指定目录下所有文件和子目录所占用的磁盘空间大小&#xff0c;并以人类可读的格…