后台回复进群一起刷力扣?
点击下方卡片可搜索文章?
读完本文,可以去力扣解决如下题目:
241.为运算表达式设计优先级(Medium)
我们号已经写了 动态规划算法,回溯(DFS)算法,BFS 算法,贪心算法,双指针算法,滑动窗口算法,现在就差个分治算法没写了,今天来写一下,集齐七颗龙珠,就能召唤神龙了~
其实,我觉得回溯、分治和动态规划算法可以划为一类,因为它们都会涉及递归。
回溯算法就一种简单粗暴的算法技巧,说白了就是一个暴力穷举算法,比如让你 用回溯算法求子集、全排列、组合,你就穷举呗,就考你会不会漏掉或者多算某些情况。
动态规划是一类算法问题,肯定是让你求最值的。因为动态规划问题拥有 最优子结构,可以通过状态转移方程从小规模的子问题最优解推导出大规模问题的最优解。
分治算法呢,可以认为是一种算法思想,通过将原问题分解成小规模的子问题,然后根据子问题的结果构造出原问题的答案。这里有点类似动态规划,所以说运用分治算法也需要满足一些条件,你的原问题结果应该可以通过合并子问题结果来计算。
其实这几个算法之间界定并没有那么清晰,有时候回溯算法加个备忘录似乎就成动态规划了,而分治算法有时候也可以加备忘录进行剪枝。
我觉得吧,没必要过分纠结每个算法的定义,定义这东西无非文学词汇而已,反正能把题做出来你说这是啥算法都行,所以大家还是得多刷题,刷出感觉,各种算法都手到擒来。
最典型的分治算法就是归并排序了,核心逻辑如下:
void sort(int[] nums, int lo, int hi) {
int mid = (lo + hi) / 2;
/****** 分 ******/
// 对数组的两部分分别排序
sort(nums, lo, mid);
sort(nums, mid + 1, hi);
/****** 治 ******/
// 合并两个排好序的子数组
merge(nums, lo, mid, hi);
}
「对数组排序」是一个可以运用分治思想的算法问题,只要我先把数组的左半部分排序,再把右半部分排序,最后把两部分合并,不就是对整个数组排序了吗?
下面来看一道具体的算法题。
添加括号的所有方式
我来借力扣第 241 题讲讲什么是分治算法,先看看题目: