Data Structure 之 算法设计策略
1. 穷举法
基本思想:列举问题的所有可能解,并用约束条件逐一进行判定,找出符合约束条件的解。
穷举法的关键在于问题的可能解的列举和可能解的判别。
例如:凑数问题
2. 递归技术
定义:直接或间接调用自身的过程
递归三要素:
(1)问题形式:返回结果是什么?需要哪些入口参数?
(2)递归规则:问题如何进行分解?
(3)终结条件:什么情况下可以无需套用递归规则直接求解?
3. 分治法
基本思想:待解问题若可以被分解成若干个相互独立的、与原问题同类型的、规模小于原问题的子问题,则可以先求解子问题,再合并子问题的解来得到原问题的解。
设计过程分为三个阶段:(1)整个问题划分为多个子问题;(2)求解各个子问题(递归调用正设计的算法);(3)合并子问题的解,得到原始问题的解。
分析过程:(1)建立递归方程;(2)求解;
递归方程的建立方法:
(1)设输入大小为n,T(n)为时间复杂性;
(2)当n<c,T(n)=θ(1);
(3)Divide阶段的时间复杂性:划分问题为a个子问题;每个子问题大小为n/b;划分时间可直接得到=D(n);
(4)Conquer阶段的时间复杂性:递归调用;Conquer时间=aT(n/b);
(5)Combine阶段的时间复杂性:时间可以直接得到=C(n)。
总之:
T(n)=θ(1) if n<c;
T(n)=aT(n/b)+D(n)+C(n) otherwise
求解递归方程T(n):使用Master定理
目的:求解T(n)=aT(n/b)+f(n)型方程,a>=1,b>0是常数,f(n)是函数。
方法:记住以下三种情况
定理: 假设有递推关系式 T(n) = aT(n/b) + f(n),其中 n 为问题规模,a 为递推的子问题数量,n/b 为每个子问题的规模(假设每个子问题的规模基本一样),f(n) 为递推以外进行的计算工作。
a≥1,b>1为常数,f(n) 为函数,T(n) 为非负整数。则有以下结果:

那么


那么


且对于某个常数 c<1 和 所有充分大的 n
有

那么

4. 动态(Dynamic)规划算法
基本思想:动态规划算法常用来求解最优化问题;
其思想是:问题的最优解如果可以由子问题的最优解推导得到,则可以先求解子问题的最优解,在构造原问题的最优解;若子问题有较多的重复出现,则可以自底向上从最终子问题向原问题逐步求解。
优化问题的特点:
优化问题:给定一个代价函数,在解空间中搜索具有最小或最大代价的优化解;
优化问题的特点:(1)可划分为多个子问题,优化解包含子问题的优化解;(2)子问题的解被重复使用
动态规划特点:
(1)把原始问题划分成一系列子问题;
(2)求解每个子问题仅一次,并将其结果保存在一个表中,以后用到时直接存取,不重复计算,节省计算时间–自底向上地计算。
适用范围
一类优化问题:可分为多个相关子问题,子问题的解被重复使用
Dynamic Programming算法的优化条件:
Optimal substructure(优化子结构):当一个问题的优化解包含了子问题的优化解时,就说这个问题具有优化子结构。
Subteties(重叠子问题):在问题的求解过程中,很多子问题的解将被多次使用。
典型:
集合划分问题:存在一个正整数集合S={a1, a2, …, an},将其划分为两个集合,使得划分得到的两个集合中元素和差的绝对值最小。
例如:矩阵连乘、备忘录方法
5. 贪心算法(Greedy算法)
基本思想:通过做出当前看来最优的选择(贪心选择,也就是说贪心算法并不从整体最优考虑,它所做出的选择只是在某种意义上的局部最优选择),将原问题规模缩小,如此反复,之道得到最终解;
贪心算法并非对所有问题都能得到整体最优解。
Greedy算法产生优化解的条件:(1)Greedy-choice-property;(2)Optimal substructure
Greedy选择性:若一个优化问题的全局优化解可以通过局部优化选择得到,则该问题称为具有Greedy选择性。(一个问题是否具有Greedy选择性需证明)
Optimal substructure(优化子结构):当一个问题的优化解包含了子问题的优化解时,就说这个问题具有优化子结构。
基本要素:
(1)贪心选择性质:所求问题的整体最优解可由一系列局部最优解选择得到;动态规划是由子问题的解得到当前问题的解,贪心算法则是由当前局部问题导出子问题;确定一个问题是否具有贪心选择性质,需要证明问题的一个整体最优解是从贪心选择开始的;
(2)最优子结构性质:通过局部最优选择,原问题将被化简为类似的子问题;亦即是说,整体最优解中包含子问题的最优解。
注意:可用Greedy方法时,动态规划方法可能不适用;可用动态规划方法时,Greedy方法可能不适用。
典型:任务选择问题
例如:迪杰斯特拉(Dijkstra)算法用于求解图上的单源点最短路径。
6. 回溯法
回溯法是一种通用性解法,可以看作是带优化的穷举法。
基本思想:在一棵含有问题全部可能解的状态空间树上进行深度优先搜索,解为叶子节点,搜索过程中每到达到一个结点时,判断该结点为根的子树是否含有问题的解,如果不含有问题的解,则放弃该子树的搜索,退回到上层父结点,继续下一步深度优先搜索过程。
在回溯法中,并不是优先构造出整棵状态空间树,再进行搜索,而是在搜索过程中,逐步构造出状态空间树,即边搜索,边构造。
回溯法的使用:
(1).确定问题状态结构;
(2).分析问题状态空间树;
(3).确定深度搜索与回溯规则;
(4).确定解状态判别规则。
子集和问题:
问题:给定由n个不同正数组成的集合w={wi},和正数M,求所有和等于M的自己的集合;
问题状态:可以设想集合中的每个正数都有选取何不选取两种可能,w的一个子集即为一个问题状态,可以表述为对每个元素选取或不选取的一个组合。
问题状态空间树:由空集开始,依次对每个元素进行选取和不选取两种选择,就可以得到W的全部子集,选取过程就可构成一个状态空间树。
按照回溯法思想,从状态树的根结点出发,做深度优先搜索;为便于计算,将w中的整数按从小到大排序;当在某一状态A下依次尝试加入和不加入Wi,若 状态A下的和 + Wi > M,则停止对该结点的搜索;若 状态A下的和 + Wi < M,也可停止对该结点的搜索;
回溯法分析:
(1)一个可以用回溯法求解的问题,通常可以表述为以下形式:对于由n元组(x1,x2,x3...xn)组成的状态空间E={(x1...xn)},给定n元组上的一个约束集D:求E中满足D的全部约束条件的所有n元组。将E中满足D的全部约束条件的一个n元组称为问题的一个解。
7. 限界剪枝法
也称分支定界法。
基本思想:与回溯法相似,也是对状态空间树进行搜索求解,不同的是分支定界法的求解目标是要找到使得某一目标函数极大或极小的一个解结点,即某种意义下的最优解。在算法设计上,不仅通过约束条件来控制搜索路径,还通过目标函数的限界来减少搜索规模;在进行搜索时通常先进行广度拓展,将满足约束条件且不越过目标函数的子结点加入到活结点表中等待搜索;
常见的活结点表:队列式(FIFO)、栈式(LIFO)、优先队列式(PQ)
例如:最小耗费搜索法(15迷问题)
Data Structure 之 算法设计策略的更多相关文章
- ✡ leetcode 170. Two Sum III - Data structure design 设计two sum模式 --------- java
Design and implement a TwoSum class. It should support the following operations: add and find. add - ...
- LeetCode初级算法--设计问题02:最小栈
LeetCode初级算法--设计问题02:最小栈 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...
- [LeetCode] All O`one Data Structure 全O(1)的数据结构
Implement a data structure supporting the following operations: Inc(Key) - Inserts a new key with va ...
- [LeetCode] Two Sum III - Data structure design 两数之和之三 - 数据结构设计
Design and implement a TwoSum class. It should support the following operations:add and find. add - ...
- Python数据结构与算法设计总结篇
1.Python数据结构篇 数据结构篇主要是阅读[Problem Solving with Python]( http://interactivepython.org/courselib/static ...
- 算法设计和数据结构学习_5(BST&AVL&红黑树简单介绍)
前言: 节主要是给出BST,AVL和红黑树的C++代码,方便自己以后的查阅,其代码依旧是data structures and algorithm analysis in c++ (second ed ...
- LeetCode Two Sum III - Data structure design
原题链接在这里:https://leetcode.com/problems/two-sum-iii-data-structure-design/ 题目: Design and implement a ...
- Leetcode: All O`one Data Structure
Implement a data structure supporting the following operations: Inc(Key) - Inserts a new key with va ...
- LeetCode 笔记27 Two Sum III - Data structure design
Design and implement a TwoSum class. It should support the following operations: add and find. add - ...
随机推荐
- 第二百二十三天 how can I 坚持
今天双十一,过得有点郁闷,昨天鱼死了不说,抢的羽绒服今天才发现是棉服,结果又买了个海澜之家的,搞的今天凌晨买的东西全都写退了,除了小米耳机. 光棍节,好纠结.爱要怎么说出口,你才不会拒绝啊,愁人啊. ...
- C# Keynote
[C# Keynote] 1. Main 方法必须包含在一个类内,参数类型.返回值类型可以有多种变化. // Hello1.cs public class Hello1 { public static ...
- redhat6.4升级openssh至6.7
1:简介 最近浙江电信对线上服务器进行漏洞扫描,暴露出原有的openssh有漏洞,建议升级openssh版本: 2:操作环境 Red Hat Enterprise Linux Server relea ...
- MSSQL手札二 MSSQL的触发器
触发器,就是在对表做DML操作的时候,触发一些其他的事件,触发器一般用在check约束更加复杂的约束上面,是一种特殊的存储过程,不可以被主动调用. 语法如下: CREATE TRIGGER trigg ...
- C#委托及事件处理机制浅析
事件可以理解为某个对象所发出的消息,以通知特定动作(行为)的发生或状态的改变.行为的发生可能是来自用户交互,如鼠标点击:也可能源自其它的程序逻辑.在这里,触发事件的对象被称为事件(消息)发出者(sen ...
- 欧几里德&扩展以及求解线性方程学习总结--附上poj1061解题报告
欧几里德算法: 欧几里德就是辗转相除法,调用这个gcd(a,b)这个函数求解a,b的最大公约数 公式: gcd(a,b)=gcd(b,a%b):并且gcd(a,b)=gcd(b,a)=gcd(-a,b ...
- 如何在tomcat安装部署php项目
java开发者都知道,tomcat是用来部署java web项目的.前几天老k偶然得知PHP/Java Bridge,通过它可以实现在jsp和php之间共享session,详见<如何实现jsp和 ...
- 批处理脚本命令行方式关闭Windows服务
对于一些不常用的Windows Services,可以通过设置其启动类型为"禁用"而将其关闭.这种关闭方式是长期性的,电脑重启之后仍然起作用. 有时候希望在批处理脚本里通过命令行方 ...
- CloudStack 4.2 与CloudStack 4.1二级存储API发生变化
CloudStack 4.1查看二级存储 http://192.168.150.16:8080/client/api?command=listHosts&response=json&s ...
- oracle 创建同义词
1.语法: 同义词 (SYNONMY) CREATE SYNONYM同义词名FOR 表名; CREATE SYNONYM同义词名FOR 表名@数据库链接名; Create synonym synony ...