class038 经典递归解析【算法】

class038 经典递归解析

算法讲解038【必备】常见经典递归过程解析

在这里插入图片描述

code1 字符串的全部子序列

// 字符串的全部子序列
// 子序列本身是可以有重复的,只是这个题目要求去重
// 测试链接 : https://www.nowcoder.com/practice/92e6247998294f2c933906fdedbc6e6a

package class038;import java.util.HashSet;// 字符串的全部子序列
// 子序列本身是可以有重复的,只是这个题目要求去重
// 测试链接 : https://www.nowcoder.com/practice/92e6247998294f2c933906fdedbc6e6a
public class Code01_Subsequences {public static String[] generatePermutation1(String str) {char[] s = str.toCharArray();HashSet<String> set = new HashSet<>();f1(s, 0, new StringBuilder(), set);int m = set.size();String[] ans = new String[m];int i = 0;for (String cur : set) {ans[i++] = cur;}return ans;}// s[i...],之前决定的路径path,set收集结果时去重public static void f1(char[] s, int i, StringBuilder path, HashSet<String> set) {if (i == s.length) {set.add(path.toString());} else {path.append(s[i]); // 加到路径中去f1(s, i + 1, path, set);path.deleteCharAt(path.length() - 1); // 从路径中移除f1(s, i + 1, path, set);}}public static String[] generatePermutation2(String str) {char[] s = str.toCharArray();HashSet<String> set = new HashSet<>();f2(s, 0, new char[s.length], 0, set);int m = set.size();String[] ans = new String[m];int i = 0;for (String cur : set) {ans[i++] = cur;}return ans;}public static void f2(char[] s, int i, char[] path, int size, HashSet<String> set) {if (i == s.length) {set.add(String.valueOf(path, 0, size));} else {path[size] = s[i];f2(s, i + 1, path, size + 1, set);f2(s, i + 1, path, size, set);}}}

code2 90. 子集 II

// 给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的组合
// 答案 不能 包含重复的组合。返回的答案中,组合可以按 任意顺序 排列
// 注意其实要求返回的不是子集,因为子集一定是不包含相同元素的,要返回的其实是不重复的组合
// 比如输入:nums = [1,2,2]
// 输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
// 测试链接 : https://leetcode.cn/problems/subsets-ii/

package class038;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;// 给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的组合
// 答案 不能 包含重复的组合。返回的答案中,组合可以按 任意顺序 排列
// 注意其实要求返回的不是子集,因为子集一定是不包含相同元素的,要返回的其实是不重复的组合
// 比如输入:nums = [1,2,2]
// 输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
// 测试链接 : https://leetcode.cn/problems/subsets-ii/
public class Code02_Combinations {public static List<List<Integer>> subsetsWithDup(int[] nums) {List<List<Integer>> ans = new ArrayList<>();Arrays.sort(nums);f(nums, 0, new int[nums.length], 0, ans);return ans;}public static void f(int[] nums, int i, int[] path, int size, List<List<Integer>> ans) {if (i == nums.length) {ArrayList<Integer> cur = new ArrayList<>();for (int j = 0; j < size; j++) {cur.add(path[j]);}ans.add(cur);} else {// 下一组的第一个数的位置int j = i + 1;while (j < nums.length && nums[i] == nums[j]) {j++;}// 当前数x,要0个f(nums, j, path, size, ans);// 当前数x,要1个、要2个、要3个...都尝试for (; i < j; i++) {path[size++] = nums[i];f(nums, j, path, size, ans);}}}}

code3 46. 全排列

// 没有重复项数字的全排列
// 测试链接 : https://leetcode.cn/problems/permutations/

package class038;import java.util.ArrayList;
import java.util.List;// 没有重复项数字的全排列
// 测试链接 : https://leetcode.cn/problems/permutations/
public class Code03_Permutations {public static List<List<Integer>> permute(int[] nums) {List<List<Integer>> ans = new ArrayList<>();f(nums, 0, ans);return ans;}public static void f(int[] nums, int i, List<List<Integer>> ans) {if (i == nums.length) {List<Integer> cur = new ArrayList<>();for (int num : nums) {cur.add(num);}ans.add(cur);} else {for (int j = i; j < nums.length; j++) {swap(nums, i, j);f(nums, i + 1, ans);swap(nums, i, j); // 特别重要,课上进行了详细的图解}}}public static void swap(int[] nums, int i, int j) {int tmp = nums[i];nums[i] = nums[j];nums[j] = tmp;}public static void main(String[] args) {int[] nums = { 1, 2, 3 };List<List<Integer>> ans = permute(nums);for (List<Integer> list : ans) {for (int num : list) {System.out.print(num + " ");}System.out.println();}}}

code4 47. 全排列 II

// 有重复项数组的去重全排列
// 测试链接 : https://leetcode.cn/problems/permutations-ii/

package class038;import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;// 有重复项数组的去重全排列
// 测试链接 : https://leetcode.cn/problems/permutations-ii/
public class Code04_PermutationWithoutRepetition {public static List<List<Integer>> permuteUnique(int[] nums) {List<List<Integer>> ans = new ArrayList<>();f(nums, 0, ans);return ans;}public static void f(int[] nums, int i, List<List<Integer>> ans) {if (i == nums.length) {List<Integer> cur = new ArrayList<>();for (int num : nums) {cur.add(num);}ans.add(cur);} else {HashSet<Integer> set = new HashSet<>();for (int j = i; j < nums.length; j++) {// nums[j]没有来到过i位置,才会去尝试if (!set.contains(nums[j])) {set.add(nums[j]);swap(nums, i, j);f(nums, i + 1, ans);swap(nums, i, j);}}}}public static void swap(int[] nums, int i, int j) {int tmp = nums[i];nums[i] = nums[j];nums[j] = tmp;}}

code5 用递归函数逆序栈

// 用递归函数排序栈
// 栈只提供push、pop、isEmpty三个方法
// 请完成无序栈的排序,要求排完序之后,从栈顶到栈底从小到大
// 只能使用栈提供的push、pop、isEmpty三个方法、以及递归函数
// 除此之外不能使用任何的容器,数组也不行
// 就是排序过程中只能用:
// 1) 栈提供的push、pop、isEmpty三个方法
// 2) 递归函数,并且返回值最多为单个整数

package class038;import java.util.Stack;// 用递归函数逆序栈
public class Code05_ReverseStackWithRecursive {public static void reverse(Stack<Integer> stack) {if (stack.isEmpty()) {return;}int num = bottomOut(stack);reverse(stack);stack.push(num);}// 栈底元素移除掉,上面的元素盖下来// 返回移除掉的栈底元素public static int bottomOut(Stack<Integer> stack) {int ans = stack.pop();if (stack.isEmpty()) {return ans;} else {int last = bottomOut(stack);stack.push(ans);return last;}}public static void main(String[] args) {Stack<Integer> stack = new Stack<Integer>();stack.push(1);stack.push(2);stack.push(3);stack.push(4);stack.push(5);reverse(stack);while (!stack.isEmpty()) {System.out.println(stack.pop());}}}

code6 用递归函数排序栈

// 用递归函数排序栈
// 栈只提供push、pop、isEmpty三个方法
// 请完成无序栈的排序,要求排完序之后,从栈顶到栈底从小到大
// 只能使用栈提供的push、pop、isEmpty三个方法、以及递归函数
// 除此之外不能使用任何的容器,数组也不行
// 就是排序过程中只能用:
// 1) 栈提供的push、pop、isEmpty三个方法
// 2) 递归函数,并且返回值最多为单个整数

package class038;import java.util.Stack;// 用递归函数排序栈
// 栈只提供push、pop、isEmpty三个方法
// 请完成无序栈的排序,要求排完序之后,从栈顶到栈底从小到大
// 只能使用栈提供的push、pop、isEmpty三个方法、以及递归函数
// 除此之外不能使用任何的容器,数组也不行
// 就是排序过程中只能用:
// 1) 栈提供的push、pop、isEmpty三个方法
// 2) 递归函数,并且返回值最多为单个整数
public class Code06_SortStackWithRecursive {public static void sort(Stack<Integer> stack) {int deep = deep(stack);while (deep > 0) {int max = max(stack, deep);int k = times(stack, deep, max);down(stack, deep, max, k);deep -= k;}}// 返回栈的深度// 不改变栈的数据状况public static int deep(Stack<Integer> stack) {if (stack.isEmpty()) {return 0;}int num = stack.pop();int deep = deep(stack) + 1;stack.push(num);return deep;}// 从栈当前的顶部开始,往下数deep层// 返回这deep层里的最大值public static int max(Stack<Integer> stack, int deep) {if (deep == 0) {return Integer.MIN_VALUE;}int num = stack.pop();int restMax = max(stack, deep - 1);int max = Math.max(num, restMax);stack.push(num);return max;}// 从栈当前的顶部开始,往下数deep层,已知最大值是max了// 返回,max出现了几次,不改变栈的数据状况public static int times(Stack<Integer> stack, int deep, int max) {if (deep == 0) {return 0;}int num = stack.pop();int restTimes = times(stack, deep - 1, max);int times = restTimes + (num == max ? 1 : 0);stack.push(num);return times;}// 从栈当前的顶部开始,往下数deep层,已知最大值是max,出现了k次// 请把这k个最大值沉底,剩下的数据状况不变public static void down(Stack<Integer> stack, int deep, int max, int k) {if (deep == 0) {for (int i = 0; i < k; i++) {stack.push(max);}} else {int num = stack.pop();down(stack, deep - 1, max, k);if (num != max) {stack.push(num);}}}// 为了测试// 生成随机栈public static Stack<Integer> randomStack(int n, int v) {Stack<Integer> ans = new Stack<Integer>();for (int i = 0; i < n; i++) {ans.add((int) (Math.random() * v));}return ans;}// 为了测试// 检测栈是不是从顶到底依次有序public static boolean isSorted(Stack<Integer> stack) {int step = Integer.MIN_VALUE;while (!stack.isEmpty()) {if (step > stack.peek()) {return false;}step = stack.pop();}return true;}// 为了测试public static void main(String[] args) {Stack<Integer> test = new Stack<Integer>();test.add(1);test.add(5);test.add(4);test.add(5);test.add(3);test.add(2);test.add(3);test.add(1);test.add(4);test.add(2);sort(test);while (!test.isEmpty()) {System.out.println(test.pop());}// 随机测试int N = 20;int V = 20;int testTimes = 20000;System.out.println("测试开始");for (int i = 0; i < testTimes; i++) {int n = (int) (Math.random() * N);Stack<Integer> stack = randomStack(n, V);sort(stack);if (!isSorted(stack)) {System.out.println("出错了!");break;}}System.out.println("测试结束");}}

code7 打印n层汉诺塔问题的最优移动轨迹

// 打印n层汉诺塔问题的最优移动轨迹

package class038;// 打印n层汉诺塔问题的最优移动轨迹
public class Code07_TowerOfHanoi {public static void hanoi(int n) {if (n > 0) {f(n, "左", "右", "中");}}public static void f(int i, String from, String to, String other) {if (i == 1) {System.out.println("移动圆盘 1 从 " + from + " 到 " + to);} else {f(i - 1, from, other, to);System.out.println("移动圆盘 " + i + " 从 " + from + " 到 " + to);f(i - 1, other, to, from);}}public static void main(String[] args) {int n = 3;hanoi(n);}}

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

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

相关文章

dpkg: error: dpkg frontend lock is locked by another process

报错截图 报错原因 ubuntu 系统利用 dpkg 离线安装服务时出现该错误 错误原因为 dpkg前端锁被另一个进程锁定 但是 ps aux |grep dpkg没有进程列表 解决方法 使用以下命令查看占用进程 lsof /var/lib/dpkg/lock-frontend 杀死该进程 rootubuntu:/opt/AutoPenetration# k…

土壤水分传感器土壤体积含水率含量监测仪器

产品概述 外型小巧轻便&#xff0c;便于携带和连接。 土壤水分传感器由电源模块、变送模块、漂零及温度补偿模块、数据处理模块等组成。传感器内置信号采样及放大、漂零及温度补偿功能&#xff0c;用户接口简洁、方便。 功能特点 ◆本传感器体积小巧化设计&#xff0c;测量…

IntelliJ idea卡顿解决,我遇到的比较管用的方案

Setttings> Build, Execution,Deployment>Debugger> Data Views> Java 取消 Enable "toString()" object view; Speed up debugging in IntelliJ Yesterday, I observed painfully slow debugging in IntelliJ. Every step over or step in took almost…

你知道怎样在 Python 中管理内存吗

memray 是一个Python库&#xff0c;它提供了一种可视化内存管理工具&#xff0c;可以帮助Python开发人员更好地理解和优化他们的代码中的内存使用情况。 它是由彭博社开发的&#xff0c;可用于分析Python程序中的内存泄漏和其他内存问题。以下是memray库的使用场景和入门案例。…

记录 | linux手动清理 buff/cache

linux下手动清理 buff/cache 切换到 root 权限 # 这个drop_caches文件可以设置的值分别为1、2、3 echo 1 > /proc/sys/vm/drop_caches # 表示清除pagecache echo 2 > /proc/sys/vm/drop_caches # 表示清除回收slab分配器中的对象&#xff08;包括目录项缓存和inode缓…

Transformer中的layer norm(包含代码解释)

在transformer中存在add&norm操作&#xff0c;add操作很简单&#xff0c;就是把注意力矩阵和原来的矩阵相加&#xff0c;也就是残差链接&#xff0c;可以有效减少梯度消失。 下图为layer norm的解释图&#xff0c;可以看出layer norm是针对一个token来做的归一化操作。 具…

空间运算设备-Apple Vision Pro

苹果以其在科技领域的创新而闻名&#xff0c;他们致力于推动技术的边界&#xff0c;这在他们的产品中表现得非常明显。他们尝试开发一项的新型突破性显示技术。在 2023 年 6 月 5 日官网宣布将发布 Apple Vision Pro 头戴空间设备&#xff0c;我们一起来了解一下 Apple Vision …

openharmony 开发环境搭建和系统应用编译傻瓜教程

一、DevEco Studio 安装 当前下载版本有两个&#xff0c;由于低版本配置会有各种问题&#xff0c;我选择高版本安装 低版本下载链接 HUAWEI DevEco Studio和SDK下载和升级 | HarmonyOS开发者 高版本下载链接 OpenAtom OpenHarmony 解压后安装 双击安装 安装配置 二、创建测…

一款Java实现的玩爆工具

这是一款涵盖娱乐到工作的软件程序&#xff0c;模块菜单包含&#xff1a;精选、博客园、观天下、听雨楼、短视频、电影、电视剧、藏金阁、云存储等诸多功能于一身的软件&#xff0c;下面我们来介绍一下软件的一些功能&#xff1a; 博客园&#xff1a;这是一个可以预览博客也可以…

openlayers地图使用---跟随地图比例尺动态标绘大小的一种方式3

openlayers地图使用—跟随地图比例尺动态标绘大小的一种方式 预期&#xff1a;随着地图比例尺放大缩小&#xff0c;地图上的标绘随着变化尺寸 思路&#xff1a;通过VectorImage和动态修改Feature尺寸实现Feature跟随地图比例尺尺寸变化 优点&#xff1a;结合第1和第2种方式的…

奇点云2023数智科技大会来了,“双12”直播见!

企业数字化进程深入的同时&#xff0c;也在越来越多的新问题中“越陷越深”&#xff1a; 数据暴涨&#xff0c;作业量和分析维度不同以往&#xff0c;即便加了机器&#xff0c;仍然一查就崩&#xff1b; 终于搞定新增渠道数据的OneID融合&#xff0c;又出现几个渠道要变更&…

VMware Workstation安装统信UOS桌面操作系统 V20-1060(11月更新)专业版

本文尝试在VMware Workstation环境下安装统信UOS桌面操作系统最新的V20-1060专业版。 一、测试环境 1、VMware Workstation版本 2、 统信UOS桌面操作系统版本 2.1 官网地址 统信UOS下载官网 2.2 下载页面如图 2.3 官网镜链接 统信UOS官网V20-1060专业版镜像链接 哈希…