算法习题之动态规划
动态规划
- 习题1 打印n层汉诺塔从最左边移动到最右边的全部过程
- 习题2 给你一个栈,请你逆序这个栈,不能申请额外的数据结构,只能使用递归函数。 如何实现?
- 习题3 打印一个字符串的全部子序列,打印一个字符串的全部子序列,要求不要出现重复字面值的子序列
- 习题4 打印一个字符串的全部排列,要求不要出现重复的排列
1.什么暴力递归可以继续优化?
有重复调用同一个子问题的解,这种递归可以优化
如果每一个子问题都是不同的解,无法优化也不用优化
2.暴力递归和动态规划的关系
某一个暴力递归,有解的重复调用,就可以把这个暴力递归优化成动态规划
任何动态规划问题,都一定对应着某一个有重复过程的暴力递归
但不是所有的暴力递归,都一定对应着动态规划
3.如何找到某个问题的动态规划方式?
1)设计暴力递归:重要原则+4种常见尝试模型!重点!
2)分析有没有重复解:套路解决
3)用记忆化搜索 -> 用严格表结构实现动态规划:套路解决
4)看看能否继续优化:套路解决
4.面试中设计暴力递归过程的原则
1)每一个可变参数的类型,一定不要比int类型更加复杂
2)原则1)可以违反,让类型突破到一维线性结构,那必须是单一可变参数
3)如果发现原则1)被违反,但不违反原则2),只需要做到记忆化搜索即可
4)可变参数的个数,能少则少
5.常见的4种尝试模型
1)从左往右的尝试模型
2)范围上的尝试模型
3)多样本位置全对应的尝试模型
4)寻找业务限制的尝试模型
习题1 打印n层汉诺塔从最左边移动到最右边的全部过程
public static void hanoi1(int n) {leftToRight(n);}// 请把1~N层圆盘 从左 -> 右public static void leftToRight(int n) {if (n == 1) { // base caseSystem.out.println("Move 1 from left to right");return;}leftToMid(n - 1);System.out.println("Move " + n + " from left to right");midToRight(n - 1);}// 请把1~N层圆盘 从左 -> 中public static void leftToMid(int n) {if (n == 1) {System.out.println("Move 1 from left to mid");return;}leftToRight(n - 1);System.out.println("Move " + n + " from left to mid");rightToMid(n - 1);}public static void rightToMid(int n) {if (n == 1) {System.out.println("Move 1 from right to mid");return;}rightToLeft(n - 1);System.out.println("Move " + n + " from right to mid");leftToMid(n - 1);}public static void midToRight(int n) {if (n == 1) {System.out.println("Move 1 from mid to right");return;}midToLeft(n - 1);System.out.println("Move " + n + " from mid to right");leftToRight(n - 1);}public static void midToLeft(int n) {if (n == 1) {System.out.println("Move 1 from mid to left");return;}midToRight(n - 1);System.out.println("Move " + n + " from mid to left");rightToLeft(n - 1);}public static void rightToLeft(int n) {if (n == 1) {System.out.println("Move 1 from right to left");return;}rightToMid(n - 1);System.out.println("Move " + n + " from right to left");midToLeft(n - 1);}public static void hanoi2(int n) {if (n > 0) {func(n, "left", "right", "mid");}}public static void func(int N, String from, String to, String other) {if (N == 1) { // baseSystem.out.println("Move 1 from " + from + " to " + to);} else {func(N - 1, from, other, to);System.out.println("Move " + N + " from " + from + " to " + to);func(N - 1, other, to, from);}}public static class Record {public boolean finish1;public int base;public String from;public String to;public String other;public Record(boolean f1, int b, String f, String t, String o) {finish1 = false;base = b;from = f;to = t;other = o;}}public static void hanoi3(int N) {if (N < 1) {return;}Stack<Record> stack = new Stack<>();stack.add(new Record(false, N, "left", "right", "mid"));while (!stack.isEmpty()) {Record cur = stack.pop();if (cur.base == 1) {System.out.println("Move 1 from " + cur.from + " to " + cur.to);if (!stack.isEmpty()) {stack.peek().finish1 = true;}} else {if (!cur.finish1) {stack.push(cur);stack.push(new Record(false, cur.base - 1, cur.from, cur.other, cur.to));} else {System.out.println("Move " + cur.base + " from " + cur.from + " to " + cur.to);stack.push(new Record(false, cur.base - 1, cur.other, cur.to, cur.from));}}}}public static void main(String[] args) {int n = 3;hanoi1(n);System.out.println("============");hanoi2(n);
// System.out.println("============");
// hanoi3(n);}
习题2 给你一个栈,请你逆序这个栈,不能申请额外的数据结构,只能使用递归函数。 如何实现?
public static void reverse(Stack<Integer> stack) {if (stack.isEmpty()) {return;}int i = f(stack);reverse(stack);stack.push(i);}// 栈底元素移除掉// 上面的元素盖下来// 返回移除掉的栈底元素public static int f(Stack<Integer> stack) {int result = stack.pop();if (stack.isEmpty()) {return result;} else {int last = f(stack);stack.push(result);return last;}}public static void main(String[] args) {Stack<Integer> test = new Stack<Integer>();test.push(1);test.push(2);test.push(3);test.push(4);test.push(5);reverse(test);while (!test.isEmpty()) {System.out.println(test.pop());}}
习题3 打印一个字符串的全部子序列,打印一个字符串的全部子序列,要求不要出现重复字面值的子序列
// s -> "abc" ->public static List<String> subs(String s) {char[] str = s.toCharArray();String path = "";List<String> ans = new ArrayList<>();process1(str, 0, ans, path);return ans;}// str 固定参数// 来到了str[index]字符,index是位置// str[0..index-1]已经走过了!之前的决定,都在path上// 之前的决定已经不能改变了,就是path// str[index....]还能决定,之前已经确定,而后面还能自由选择的话,// 把所有生成的子序列,放入到ans里去public static void process1(char[] str, int index, List<String> ans, String path) {if (index == str.length) {ans.add(path);return;}// 没有要index位置的字符process1(str, index + 1, ans, path);// 要了index位置的字符process1(str, index + 1, ans, path + String.valueOf(str[index]));}public static List<String> subsNoRepeat(String s) {char[] str = s.toCharArray();String path = "";HashSet<String> set = new HashSet<>();process2(str, 0, set, path);List<String> ans = new ArrayList<>();for (String cur : set) {ans.add(cur);}return ans;}public static void process2(char[] str, int index, HashSet<String> set, String path) {if (index == str.length) {set.add(path);return;}String no = path;process2(str, index + 1, set, no);String yes = path + String.valueOf(str[index]);process2(str, index + 1, set, yes);}public static void main(String[] args) {String test = "acccc";List<String> ans1 = subs(test);List<String> ans2 = subsNoRepeat(test);for (String str : ans1) {System.out.println(str);}System.out.println("=================");for (String str : ans2) {System.out.println(str);}System.out.println("=================");}
习题4 打印一个字符串的全部排列,要求不要出现重复的排列
public static List<String> permutation1(String s) {List<String> ans = new ArrayList<>();if (s == null || s.length() == 0) {return ans;}char[] str = s.toCharArray();ArrayList<Character> rest = new ArrayList<Character>();for (char cha : str) {rest.add(cha);}String path = "";f(rest, path, ans);return ans;}public static void f(ArrayList<Character> rest, String path, List<String> ans) {if (rest.isEmpty()) {ans.add(path);} else {int N = rest.size();for (int i = 0; i < N; i++) {char cur = rest.get(i);rest.remove(i);f(rest, path + cur, ans);rest.add(i, cur);}}}public static List<String> permutation2(String s) {List<String> ans = new ArrayList<>();if (s == null || s.length() == 0) {return ans;}char[] str = s.toCharArray();g1(str, 0, ans);return ans;}public static void g1(char[] str, int index, List<String> ans) {if (index == str.length) {ans.add(String.valueOf(str));} else {for (int i = index; i < str.length; i++) {swap(str, index, i);g1(str, index + 1, ans);swap(str, index, i);}}}public static List<String> permutation3(String s) {List<String> ans = new ArrayList<>();if (s == null || s.length() == 0) {return ans;}char[] str = s.toCharArray();g2(str, 0, ans);return ans;}public static void g2(char[] str, int index, List<String> ans) {if (index == str.length) {ans.add(String.valueOf(str));} else {boolean[] visited = new boolean[256];for (int i = index; i < str.length; i++) {if (!visited[str[i]]) {visited[str[i]] = true;swap(str, index, i);g2(str, index + 1, ans);swap(str, index, i);}}}}public static void swap(char[] chs, int i, int j) {char tmp = chs[i];chs[i] = chs[j];chs[j] = tmp;}public static void main(String[] args) {String s = "acc";List<String> ans1 = permutation1(s);for (String str : ans1) {System.out.println(str);}System.out.println("=======");List<String> ans2 = permutation2(s);for (String str : ans2) {System.out.println(str);}System.out.println("=======");List<String> ans3 = permutation3(s);for (String str : ans3) {System.out.println(str);}}
相关文章:
算法习题之动态规划
动态规划习题1 打印n层汉诺塔从最左边移动到最右边的全部过程习题2 给你一个栈,请你逆序这个栈,不能申请额外的数据结构,只能使用递归函数。 如何实现?习题3 打印一个字符串的全部子序列,打印一个字符串的全部子序列,…...
顺序表【数据结构】
文章目录:star2:1. 顺序表概念:star2:2. 框架3. 基本功能3.1 头文件:star:3.2 初始化:star:3.3 扩容:star:3.4 打印:star:3.5 尾插:star:3.6 头插:star:3.7 尾删:star:3.8 头删:star:3.9 指定插入:star:3.10 指定删除:star:3.11 查找:star2:3.12 注意事项4. 顺序表的缺点&#…...
SNAP中根据入射角和干涉图使用波段计算器计算垂直形变--以门源地震为例
SNAP中根据入射角和相干图使用波段计算器计算垂直形变--以门源地震为例0 写在前面1 具体步骤1.1 准备数据1.2 在SNAP中打开波段运算Band Maths1.3 之前计算的水平位移displacement如下图数据的其他处理请参考博文在SNAP中用sentinel-1数据做InSAR测量,以门源地震为例…...
Ubuntu20.04中Docker安装与配置
一、安装 1、卸载可能存在的旧版本 sudo apt-get remove docker docker-engine docker-ce docker.io2、更新apt包索引 sudo apt-get update显示“正在读取软件包列表… 完成” 3、安装以下包以使apt可以通过HTTPS使用存储库(repository) sudo apt-get install -y apt-tran…...
pytorch权值初始化和损失函数
pytorch权值初始化和损失函数 权值初始化 梯度消失与爆炸 针对上面这个两个隐藏层的神经网络,我们求w2的梯度 可以发现,w2的梯度与H1(上一层网络的输出)有很大的关系,当h1趋近于0时,w2的梯度也趋近于0&am…...
maven将jar文件上传至本地仓库及私服
maven官方仓库有些依赖并不存在,现在项目都是maven直接获取jar,当maven获取不到时,需要我们把jar上传至maven仓库。已 ImpalaJDBC41.jar 文件为例,如:希望上传后,设置的依赖为:<dependency&g…...
前端学习第三阶段-第1、2章 JavaScript 基础语法
01第一章 JavaScript网页编程课前导学 1-1 JavaScript网页编程课前导学 02第二章 JavaScript 基础语法 2-1 计算机基础和Javascript介绍 01-计算机基础导读 02-编程语言 03-计算机基础 04-JavaScript初识导读 05-初始JavaScript 06-浏览器执行JS过程 07-JS三部分组成 08-JS三种…...
hibernate学习(二)
hibernate学习(二) 一、hibernate常见配置: 1.XML提示问题配置: 二、hibernate映射的配置: (1)class标签的配置: 标签用来建立类与表之间的映射关系属性: 1.name&…...
平安银行LAMBDA实验室负责人崔孝林:提早拿到下一个计算时代入场券
量子前哨重磅推出独家专题《“量子”百人科学家》,我们将遍访全球探索赋能“量子”场景应用的百位优秀科学专家,从商业视角了解当下各行业领域的“量子”最新研究成果,多角度、多维度、多层面讲述该领域的探索历程,为读者解析商业…...
linux下进不去adb
linux 进不去adb cat /sys/kernel/debug/usb/devices 查看是否有adb口 首先查看adb是否被识别成串口 option 如果被识别成串口 方法1: https://patchwork.kernel.org/project/linux-usb/patch/20180723140220.7166-1-romain.izard.progmail.com/ diff --git a/dri…...
【SPSS】多因素方差分析详细操作教程(附案例实战)
🤵♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 目录 方差分析概述 多因素方差分析原理...
我的投稿之旅
一、铁道科学与工程学报选择这个期刊的原因是:感觉影响因子较低,而且实验室有师兄师姐中过这个期刊,所以抱着试一试的心态投了。投稿之前需要去官网注册账号由于方向不一致,被退稿了“您的稿件内容不属于本刊刊载范畴,…...
51单片机DS18B20的使用
文章目录前言一、DS18B20介绍二、单总线协议三、DS18B20引脚说明四、DS18B20程序编写1.DS18B20复位函数2.DS18B20存在检测3.DS18B20读取一个bit和一个byte函数4.DS18B20写一个字节函数5.开始温度转换函数6.DS18B20初始化函数7.DS18B20读取温度函数五、代码测试总结前言 本篇文…...
Vue组件原理知识(1)
Vue 组件知识整理(1)文章目录Vue 组件知识整理(1)一、组件介绍1.1 传统方式与组件方式编写应用对比二、组件使用2.1 非单文件组件的使用**1. 组件的创建****2. 组件的注册****3. 组件的使用****4. Vue中使用组件的三大步骤总结***…...
Linux:IO库函数
目录标准库IO函数一、fopen二、fwrite三、fread四、fseek五、fclose在编写程序时,离不开IO操作,最常见的IO操作就是用printf函数进行打印,本文主要介绍的是封装后的IO库函数。 标准库IO函数 常使用的IO库函数如下: 函数作用fop…...
Go爬虫学习笔记
N002.02 Go分布式爬虫实战 开篇 学习三阶段 入门,照猫画虎底层,了解方方面面,深入阅读源码和书籍借助开源组件来进行复杂设计,窥探各个组件赋能业务 分布式系统: 扩展性一致性可用性高并发微服务 爬虫࿱…...
数据结构课程设计:高铁信息管理系统(C++实现)
目录 简介实验输出实验要求代码运行环境结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过国家奖学金,有幸在竞赛中拿过一些国奖…...
Python 模块之 datetime
datetime 对象格式化为字符串 标准转换格式符号: %a 本地星期的短名称 如:Sun, Mon, ..., Sat (en_US); So, Mo, ..., Sa (de_DE) %A 本地星期全名称 如 :Sunday, Monday, ..., Saturday (en_US);Sonntag, Montag, ..., Samstag (de_DE) %w…...
linux安装编译ffmpeg
ffmpeg下载:http://ffmpeg.org/releases可以下载适合自己的版本。我下载的是5.0版本,然后解压:tar xvf ffmpeg-5.0.tar.gz进入ffmpegcd ffmpeg-5.0编译ffmpeg./configure --prefix/root/ffmpeg //编译文件存放的路径如果是交叉编译添加以下参…...
嵌入式Linux驱动开发(二)LED驱动
1. Linux下LED驱动原理 与裸机区别在于,编写驱动要符合linux驱动框架规范。裸机直接对寄存器物理地址进行读写,linux下需要经过MMU。 1.1 地址映射相关概念 1)MMU(Memory Manage Unit - 内存管理单元): …...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
Java后端检查空条件查询
通过抛出运行异常:throw new RuntimeException("请输入查询条件!");BranchWarehouseServiceImpl.java // 查询试剂交易(入库/出库)记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...
qt 双缓冲案例对比
双缓冲 1.双缓冲原理 单缓冲:在paintEvent中直接绘制到屏幕,绘制过程被用户看到 双缓冲:先在redrawBuffer绘制到缓冲区,然后一次性显示完整结果 代码结构 单缓冲:所有绘制逻辑在paintEvent中 双缓冲:绘制…...
Three.js + Vue3 加载GLB模型项目代码详解
本说明结合 src/App.vue 代码,详细解释如何在 Vue3 项目中用 three.js 加载并显示 glb 模型。 1. 依赖与插件导入 import {onMounted, onUnmounted } from vue import * as THREE from three import Stats from stats.js import {OrbitControls } from three/examples/jsm/co…...
