回溯递归的剪枝模版

news/2024/11/20 17:33:29/

题目传送门
主要看灵神的二分模版,如何使用递归实现在 O ( m k ) O(mk) O(mk)时间内,实现对于二分中每个条件的判断。
一般套路:

dfs函数返回值为布尔类型

循环中使用一个dfs,如果其返回true,那么直接这个dfs返回true

技巧:
一个引用类型的值作为终止条件的判断,所有的dfs共享这个变量。
灵神代码:

class Solution {// 返回是否找到 k 个子数组和bool dfs(vector<vector<int>> &mat, int &left_k, int i, int s) {if (i < 0) // 能递归到这里,说明数组和不超过二分的 midreturn --left_k == 0; // 是否找到 k 个for (int x: mat[i]) { // 「枚举选哪个」,注意 mat[i] 是有序的if (x - mat[i][0] > s) // 选 x 不选 mat[i][0]break; // 剪枝:后面的元素更大,无需枚举if (dfs(mat, left_k, i - 1, s - (x - mat[i][0]))) // 选 x 不选 mat[i][0]return true; // 找到 k 个就一直返回 true,不再递归}return false;}public:int kthSmallest(vector<vector<int>> &mat, int k) {int sl = 0, sr = 0;for (auto &row: mat) {sl += row[0];sr += row.back();}// 二分模板 https://www.bilibili.com/video/BV1AP41137w7/int left = sl - 1, right = sr; // 开区间 (sl-1,sr)while (left + 1 < right) { // 开区间不为空// 循环不变量:// f(left) < k// f(right) >= kint mid = left + (right - left) / 2;int left_k = k;if (dfs(mat, left_k, mat.size() - 1, mid - sl)) // 先把第一列的所有数都选上right = mid; // 二分范围缩小至开区间 (left, mid)else // f(mid) < kleft = mid; // 二分范围缩小至开区间 (mid, right)}return right;}
};作者:灵茶山艾府
链接:https://leetcode.cn/problems/find-the-kth-smallest-sum-of-a-matrix-with-sorted-rows/solutions/2286593/san-chong-suan-fa-bao-li-er-fen-da-an-du-k1vd/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

时间复杂度思考:
为什么回溯的时间复杂度为 O ( m k ) O(mk) O(mk),dfs递归的过程是一棵树从顶到底,本题中如果能够递归到 i < 0 i<0 i<0,那么就是走完了一条路径,该路径花费时间 O ( m k ) O(mk) O(mk)。如果能够成功走完k条路径,那么就直接所有的dfs开始统一返回true,在此之前所有的dfs返回的都是false。
这样做的好处是,虽然每个dfs中的for循环还没结束,但是由于出现了一个true,提前终止了循环,所有就可以保证递归树中每一层的节点个数最多为k个。着实神奇,而且写法十分优雅!


http://www.ppmy.cn/news/103504.html

相关文章

Cache性能,多核,一致性

cache performance影响因素&#xff1a; 1.cache size 2.block size 3.组相连度&#xff0c;4.替换策略 目标 1.减少miss rate(可以用一个指针指向不常用的数据结构) 2.减少miss penalty 3.减少hit cost 多核系统下的cache设计 分布or集中 集中 优点 缺点 资源竞争,不平等…

阿里云对象oss

1\RAM 首页 https://ram.console.aliyun.com/overview 点击用户进去 点击里面的一个用户&#xff0c;然后新建 id 和secret 上面灰色按钮&#xff0c;因为我已经绑定了两个。 "yourAccessKeyId", "yourAccessKeySecret" 这两个参数就对应上了 // 阿里云账…

rsync+inotfy实时同步

rsyncinotfy实时同步 目录 一、服务器端 二、客户端 一、服务器端 1、安装网站服务&#xff0c;启动&#xff0c;但是不写首页文件 yum -y install httpd 2、安装raync服务 yum -y install rsync 3、修改主配置文件 &#xff08;/etc/rsyncd.conf&#xff09; uid root gi…

day4 | 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、 142.环形链表II

目录&#xff1a; 链接 题目链接&#xff1a; https://leetcode.cn/problems/swap-nodes-in-pairs/ https://leetcode.cn/problems/remove-nth-node-from-end-of-list/ https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/ https://leetcode.cn/proble…

滑动窗口-单调队列模板

给定一个大小为 n≤106&#xfffd;≤106 的数组。 有一个大小为 k&#xfffd; 的滑动窗口&#xff0c;它从数组的最左边移动到最右边。 你只能在窗口中看到 k&#xfffd; 个数字。 每次滑动窗口向右移动一个位置。 以下是一个例子&#xff1a; 该数组为 [1 3 -1 -3 5 3…

【华为OD统一考试B卷 | 100分】 字符串变换最小字符串 (C++ Java JavaScript Pyhton )

文章目录 题目描述输入描述输出描述用例备注ACM输入输出模式机考代码查重c++javaScriptJavapython题目描述 给定一个字符串s,最多只能进行一次变换,返回变换后能得到的最小字符串(按照字典序进行比较)。 变换规则:交换字符串中任意两个不同位置的字符。 输入描述 一串小写…

数据库自研创新,星环科技发布国产化全面替代方案

核心技术是国之重器&#xff0c;加速推进核心领域关键技术突破&#xff0c;完成核心网络中的软硬件国产替代是国家的一项长期战略。 出品 | CSDN云计算 “聚力攻坚基础软件&#xff0c;加速分布式数据库/混合事务分析处理数据库等产品研发推广。”“十四五”规划明确&#xff0…

什么是低代码?国内常见的低代码平台有哪些?

一、什么是低代码开发&#xff1f; 低代码也称之为无代码或是 aPaas。要想了解低代码是什么&#xff0c;我们先来讨论低代码本质&#xff1f; 它是一种可视化软件开发方法&#xff0c;通过最少的编码更快地交付应用程序。 图形用户界面和拖放功能使开发过程的各个方面自动化…