算法练习
ChaosMeta
茫茫苍穹落雨燕,慢慢雾霭绕龙腾
展开
-
算法练习(35):House Robber
题意:给出一串数字,不能获取相邻的两个,取了第一个就不能取第二个,想取第二个就不能取第一个。思路与分析:这道题完全就是最小和的相反,用动态规划,思路参见http://blog.csdn.net/kingsonying/article/details/78755628动态转移方程:dp[i][0]=max{dp[i-1][0],dp[i-1][1]},dp[i][1]=dp[i-1][0]+原创 2017-12-29 17:55:39 · 442 阅读 · 0 评论 -
算法练习(28):Course Schedule II
题意:给出有向图,找出它的拓扑排序分析与思路:同样还是Course Schedule I(上一个博客)的思路,只不过在每次访问完一个结点的时候把它push起来,为什么呢?因为拓扑排序实际上就是结点按post值从小到大排序的结果,为什么呢?因此拓扑排序后一个结点的进行需要前一个结点的事情完成(遍历完),而post值代表完成的时间,所以,道理很简单(post是什么,还有基本深搜的思路参考上一个博客原创 2017-12-08 00:16:12 · 379 阅读 · 0 评论 -
算法练习(27):Course Schedule
题意:给出有向图,判断是否有环分析与思路:题目看上去简单,但是没有一个套路还是挺难想的,求有向图是否有环,有一个思路清晰又实用的方法,就是用dfs遍历同时判断是否有回边,pre[node]和post[node]分别代表访问这个点的开始时间和离开时间,一个边u->v若满足pre(v)v为回边代码:class Solution {public: vector isVisited;//可原创 2017-12-07 23:30:59 · 324 阅读 · 0 评论 -
算法练习(26):Freedom Trail
题意:像是老式电话机那种转盘,有两个字符串key,ring,key的每个字符都出现在ring中,按下key[i]这个字符意思是把ring中对应字符转到12点方向,可以顺时针或者逆时针都可以,转一位就算一步,转到之后按中间键,按一次也算一步。分析与思路:先把问题简单化,最后的按中间键对于key每个字符都要按一次,所以直接放到最后再整体加上key.length()就好。而且发现一个规律:把ring原创 2017-12-07 09:23:04 · 351 阅读 · 0 评论 -
算法练习(33):Minimum ASCII Delete Sum for Two Strings
题意:给出两个字符串,通过删除字符来使两个字符串相同,删除一个字符的耗费是这个字符的ASCII值,找出最小的耗费分析与思路:这道题也是一道动态规划题目,可以说是edit distance这道题的简化版,edit distance的操作有移动,增加删除字符操作,这里只有删除操作,所以思路还是差不多的.状态转移方程为:dp[i][j]=max{dp[i][j-1]+s2[j],dp[i-1][原创 2017-12-22 19:52:05 · 349 阅读 · 0 评论 -
算法练习(32):Delete and Earn
题意:给出一个数组,定义一个操作,从中取一个数可以获取数字表示的分数,然后要把与这个数字差的绝对值为1的数都从数组中删掉(意味着你再也得不到他们表示的分数)分析与思路:这是一道很明显的动态规划题目,当然按照这个题意还不容易想出状态转移方程,先从题意找出规律来简化一下,要取某个数时,其他等于他的数在最后肯定都会取完,因此很容易想到把重复数字归一化,然后得出每个数代表的价值(数字*个数)。然后排序原创 2017-12-22 18:10:13 · 305 阅读 · 0 评论 -
算法练习(31):最小和
题意:给出一个数组,相邻两个数至少选一个,求选出的数的和最小值。分析与思路:一个个数字的选,很容易然我想起用动态规划的方法来做,首先想到dp[i]代表考虑前i个数字时的最小和,但是又不能考虑到第i个数是否已经选,因为这涉及到我i+1时能否选的问题,第i个数如果不选,则i+1就必须选,第i个选了,则i+1可选可不选。所以状态转移方程为:dp[i][0]=dp[i-1][1];dp[i][1]=m原创 2017-12-08 21:18:49 · 726 阅读 · 0 评论 -
算法练习(30):Edit Distance
题意:两个字符串的编辑距离就是使两个字符串变得一样的操作数,做操包括插入删除替换。分析与思路:这道题是一道典型的动态规划题目,类似这种两个字符串的动态规划,一般都需要一个二维数组维护dp值。这里我用dp[i][j]表示第一个字符串的前i个字符前缀和第二个字符串的前j个前缀之间的最小编辑距离值。第一个字符串长度m,第二个字符串长度n,这样我们的目标就是dp[m][n],为了把问题简单化,每次减少原创 2017-12-08 20:28:52 · 337 阅读 · 0 评论 -
算法练习(29):Count Primes
题意:找出小于n的所有质数(素数)分析与思路:从2到根号n的每个数标出是他们倍数的数,一直到n为止。那么被标到的数必然不是素数,而从2到n之间没被标到的则为素数。代码:class Solution {public: int countPrimes(int n) { vector flags(n, false); for (int i = 2; i < sqrt(n); i+原创 2017-12-08 17:51:27 · 276 阅读 · 0 评论 -
算法练习(25):Maximum Length of Repeated Subarray
题意:找出最长公共子数组的长度分析与思路:这种对两个数组或者字符串找出公共或者其他什么规律的题,其实都可以用一种类型的思路去做,就是动态规划,对两个整体的数组的分析可以变成一个更小的问题,分析更小的,一点点减小,这题目的动态方程是:dp(i,j)=(A[i]==B[j])?[dp(i-1,j-1)+1]:0代码:class Solution {public: int findL原创 2017-11-30 14:07:10 · 275 阅读 · 0 评论 -
算法练习(36):Min Cost Climbing Stairs
题意:给出一个数组,可以从第0位或第1位开始出发,停在哪个位就要花费那个数字的消耗,停了一个位置可以往后跳一步或者两步,问走完整个数组所需最小花费。分析与思路:这道题跟上一道题是一样的思路的,动态方程有点相反而已,由于问题规定最多只能走两步,所以上一步没走,当前就不能再不走,上一步走了,当前可以选择走或者不走所以动态规划方程:dp[i][1]=max{dp[i-1][0]+cost[i],原创 2018-01-02 16:27:36 · 329 阅读 · 0 评论 -
算法练习(37):Best Time to Buy and Sell Stock
题意:实质上就是给出一个数组,找出其中最大差,条件是后面的数减去前面的数而且必须为正数(最大差为负数则结果是0)思路与分析:需要找出满足时间顺序的最大值和最小值的差,最大值要在最小值后面出现,可以使用动态规划,多个变量,要都考虑的话还是挺难考虑的。因此我觉得这算是控制变量吧,用一个minPrice表示遍历过程中当前出现的最小价格,minProfit表示当前可以得到的最大满足条件的差值。状态原创 2018-01-02 17:55:45 · 275 阅读 · 0 评论 -
算法练习(43):Network Delay Time
题意:给出一个电路,有向图,从一个源出发到遍历全部点所需要的时间。分析与思路:这道题的关键是要从题意中弄懂实际上是要我们求到所有的点的最短耗时中的最长时间。所以我用dijkstra算法求出源到所有点的最短时间,然后找出最大的值返回即可。代码:vector dst;class Solution {public: struct cmp { bool operator() (con原创 2018-01-13 19:00:27 · 403 阅读 · 0 评论 -
算法练习(42):Best Time to Buy and Sell Stock II
题意:给出一个数组,每个数代表当天股票的价格,有无数次买卖股票的机会,但是持有时不能买另一个。问最大收益。分析与思路:这道题设计到波峰波谷的概念,有两种思路。1.可以每两个相邻的票价满足有收益都买(贪婪算法)2.只买最近的极小值,只卖当前极小值后最近的极大值。代码:1.class Solution {public: int maxProfit(vector& price原创 2018-01-13 17:07:14 · 259 阅读 · 0 评论 -
算法练习(41):Unique Paths II
题意:还是从左上角走到右下角,有多少条路径,每次只能往右或者往下走一个位置,这一个格子可能有障碍物了,不能走到障碍物。思路与分析:参考我的上一篇博客(http://blog.csdn.net/KingsonYing/article/details/79052118)的思路,不同的地方就是在第一行第一列的时候,从左往右初始化第一行格子时,若出现一个障碍物,后面的都只能为0了,前面的还是为1.对于原创 2018-01-13 16:30:22 · 319 阅读 · 0 评论 -
算法练习(40):Unique Paths
题意:从左上角走到右下角,有多少条不同路径?每次只能往右或者往下走。分析与思路:首先看第一行的每个位置,都只有一条路走,第一列也是。用动态规划思路,就是每一个终点位置路径都只能由上一个位置或者左一直位置到达(每次只能往右或者往下走一个位置),所以dp[i][j]=dp[i-1][j]+dp[i][j-1].代码:class Solution {public: int uniqueP原创 2018-01-13 16:26:18 · 287 阅读 · 0 评论 -
算法练习(39):Search a 2D Matrix II
题意:每行数字从小到达,每行的最后一位比下一行的最后一位小。思路与分析:可以利用每行的最后一位来判断,可以节约寻找时间,直接判断每行的最后一位是否大于target,是则在当行最后一个开始往回找,否则,转下一行。代码:class Solution {public: bool searchMatrix(vector>& matrix, int target) { for (int原创 2018-01-13 16:21:02 · 442 阅读 · 0 评论 -
算法练习(18):Jump Game
题目:题意就是说从下标0的位置能否到达最后一个下标的位置,然后数组的每个值代表当前位置能向前走的最大步数。分析与思路:我用贪婪算法来做的,我遍历每一个下标的值同时更新最远到达的下标值(far),最后若far>=A.length()-1则说明可以到达。代码:class Solution {public: bool canJump(vector& nums) { int far原创 2017-10-19 20:39:03 · 388 阅读 · 0 评论 -
NP完全性证明
NP-complete的问题就是说这个问题既是NP又是NP-hard。NP-complete的问题就是难以在多项式时间内解决的问题。因此,当对于一个问题不会解决时,能证明它是NP完全问题,那么不会做也无可厚非了。如何证明一个问题的NP完全性呢?——使用规约首先找到一个已知的NP完全问题,然后证明这个问题能规约到想要被证明NP完全性的问题。那么就可以说它是一个NP完全问题了。原创 2017-12-28 11:34:57 · 5028 阅读 · 0 评论 -
算法练习(34):Maximum Length of Pair Chain
题意:给出一个pair数组,求最长pair链,连接规则题目讲的很清楚思路与分析:这道题我是使用动态规则算法来做的,我是先对给出的pair排序,然后dp[i]记录以第i个pair结尾的链条长度,所以我在遍历的时候每次都遍历一次0~i-1的pair看是否有可以接在第i个pair前面的,有的话,dp[i]=dp[j]+1;代码:class Solution {public: int fi原创 2017-12-28 00:42:04 · 242 阅读 · 0 评论 -
算法练习(38):Best Time to Buy and Sell Stock with Transaction Fee
题意:给出一个股票多天的价格,可以有无数次成对的买入卖出,但每次有手续费。求所能获得的最大利润思路与分析:这是一道动态规划的问题,一共就有两种状态,当前持有股票以及没有股票。我们可以用两个变量(hold,cash)分别代表这两个状态下当前赚的最多的钱。所以在遍历过程中有:cash=max{cash,hold+prices[i]-fee},hold=max{hold,cash-prices[i]原创 2018-01-03 02:41:22 · 331 阅读 · 0 评论 -
算法练习(24):Counting Bits
题意:输入一个数,然后找出小于等于它的每个非负整数的二进制形式的1的个数,用vector依次存下来返回分析与思路:这道题,我是先列出很多个数以及它的1个数来找规律的,因为这种题若要求O(n)则肯定是找数字规律的,列出的数字如下:如上所示,除开0和1,每一个2的幂之间都有规律,【2^k,2^(k+1))的前半部分是和【2^(k-1),2^k)一样的,而后半部分则为【2^(k-1),2原创 2017-11-18 20:24:32 · 298 阅读 · 0 评论 -
算法练习(21):Frog Jump
题意:给出石头的位置,然后青蛙每一跳的距离a和上一跳距离k满足(k==a||k==a-1||k==a+1),第一个石头是位置0,第一跳只能距离为1.分析与思路:这个题目用遍历搜索所有的路线是肯定可以做的,但是简单的遍历会超时,我用的方法是深度优先遍历同时排除掉不可能的情况。我用一个数据结构step来保存当前位置以及跳到这里的上一跳距离,我用一个优先队列(位置靠后的优先)保存所有出现过的step原创 2017-10-26 17:02:16 · 417 阅读 · 0 评论 -
算法练习(5):Longest Palindromic Substring
算法练习原创 2017-09-20 00:16:46 · 333 阅读 · 0 评论 -
算法练习(10):Merge k Sorted Lists
题意:把多个有序链表合并成一个有序链表。分析与思路:题目简明易懂,但是也并非想象中的易事,思维上没有什么复杂的地方,我的思路是直接把第一个和第二个序列合并成一个整体,合并方法是把第二个序列一个个插入第一个链表中。再整体和第三个序列合并,再和第四个,直到结束。代码: struct ListNode { int val; ListNode *next; Lis原创 2017-09-28 10:22:56 · 249 阅读 · 0 评论 -
算法练习(4):ZigZag Conversion
算法练习原创 2017-09-19 18:53:39 · 467 阅读 · 0 评论 -
算法练习(9):Longest Common Prefix
题意:找出所有字符串的共同最长前缀。分析与思路:这道题,比较简单,我的方法是直接以第一个字符串为基准,依次比较每一个其他的字符串的对应下标的字符跟第一个字符串的是否相同,遇到不同就直接跳出循环。代码:class Solution {public: string longestCommonPrefix(vector& strs) { string result = ""; i原创 2017-09-26 21:13:29 · 249 阅读 · 0 评论 -
算法练习(8):4Sum
题意:因为上一道题刚好是找出三个数的,这次是找出四个数的,所以就刚好放在一起做了。分析与思路:这次的解法跟上一道题的解法思路,完全一模一样,不需要改变算法,只需要在最外层再加一层循环,并不会超时。所以还是直接上代码吧代码:class Solution {public: vector> fourSum(vector& nums, int target) { vector> res原创 2017-09-26 20:58:08 · 296 阅读 · 0 评论 -
算法练习(7):3Sum
题目:题意:题目意思是从给出的数组中找出三个和为0的元素,返回所有的组合。分析与思路:对于这种题,没做过这类题的第一反应肯定是暴力求解,三次循环,超出所有的组合然后查重去掉重复的。但是这当然会超时毕竟复杂度达到了O(n3),因此必须另寻出路。为了避免一些重复的遍历,对于找和为定值的两个数时,我们有一种方便的方法:就是先把数组排序(从小到大),然后从数组两端向中间移动,和大于目标则右端指原创 2017-09-26 19:30:51 · 345 阅读 · 0 评论 -
算法练习(6):Container With Most Water
上题目先:题意:这道题的意思是,以X轴为桶底,输入n个正整数作为桶边的高,然后这些桶边所在的位置正是它们在数组中的序号,也就是说两个桶边的距离是序号差的绝对值。分析与思路:这道题目,由于是只需要找到能到达的最大容量值,看起来两层循环应该可以暴力求解的,但是我也不清楚直接暴力求解会不会超时,我是采用了一点稍微巧妙一点的方法的。我的想法是,容量大小由较短边和底长决定的,当一开始取底最长原创 2017-09-25 21:39:02 · 270 阅读 · 0 评论 -
算法练习(3):Median of Two Sorted Arrays
算法设计的练习题原创 2017-09-09 01:30:02 · 284 阅读 · 0 评论 -
算法练习(1):Add Two Numbers
算法分析与设计的练习题原创 2017-09-08 19:28:02 · 439 阅读 · 0 评论 -
算法练习(12):Longest Valid Parentheses
题意:题目是要我们找出连续有效括号的最大长度。分析与思路:括号匹配问题一般都会想到用栈来解决,我的方法就是用栈来做的。问题是找出字符串里面最长的一段的长度,也就是说可能有很多个有效段。我一开始想过用累加的方法,对于某个段,没匹配一个成功就长度加2,但是发现问题没有这么简单,这样子做会难以区分段的结束。后来我改用了字符对应的下标来计算长度,那么这样子的话就要在每一个字符的入栈出栈中伴随着对应的下原创 2017-10-08 10:13:38 · 349 阅读 · 0 评论 -
算法练习(11):Reverse Nodes in k-Group
题意:题目意思是说给出一个链表,同时输入一个比链表长度小的正整数k,然后我们要做的是对于这个链表,从左到右,每k个节点作为一个整体逆转,如上面的例子所示,但是有个规定,不能改变节点本身的值,我们要做的是通过改变节点间的链接方式实现。分析与思路:一开始肯定想过投机取巧通过改变节点的值来轻松实现,但是这题明确规定了不可以那么做,那么我们就只有老老实实改变节点连接方式实现了。我的想法是,既然要逆转k原创 2017-09-29 20:50:24 · 228 阅读 · 0 评论 -
算法练习(20):Maximum Subarray
题意:如题,找出其中的和最大的连续子数组。(注意是连续的)分析与思路:遍历所有的子数组按理论来说是可以找出来的,但是这么愚蠢的方法系统是不可能让过的,这道题是个使用动态规划很好的例子,我们可以尝试找出以某个元素作为尾元素的子数组和最大的值(我们称为L(i)),这个应该是不难的,对于第一个元素L(0)就是本身了L(0)=nums(0),但是对于后面的每一个元素作为子数组中,若要和最大,肯定需要以原创 2017-10-26 15:13:01 · 278 阅读 · 0 评论 -
算法练习(23):Is Subsequence
题意:判断一个字符串s是否是另一个字符串t的子序列,也就是说s不需要在t中是连续出现的,但s的每个字符都在t中按顺序出现过即可分析与思路:这道题比较简单,从题意就可以想出来,“s的每个字符都在t中按顺序出现过即可”,思路就是按照这句话来做,用两个指针sp,tp分别指s和t的下标,遍历,相同字符,则sp++,tp++;否则tp++;若sp能到达s的尾部,则说明满足要求,否则不满足代码:c原创 2017-11-09 12:45:03 · 275 阅读 · 0 评论 -
算法练习(22):Maximum Sum of 3 Non-Overlapping Subarrays
题意:如题,找出不相交的三个k元子数组,使得和最大,输出三个子数组的首项下标,若有多个答案,则取字典序最小的。分析与思路:这道题是一道动态规划的题,思路不难想出,一层一层来解决,先用一个数组oneSubarray记录每个位置的数组和,即:oneSubarray[i]表示sum(nums(i-k+1)~nums(i)),然后用twoSubarray[i]表示max(oneSubarray[k原创 2017-10-31 00:42:21 · 323 阅读 · 0 评论 -
算法练习(14):词法分析程序设计
刚做完正则匹配的题目,现在顺便也把这道编译原理上实现的词法分析程序分享一下吧,虽然挺简单的。题意:如上图,说的很清楚,就是分析出输入的字符串的每个词属于哪种类型中的哪一项,标识符和整数是出现过的添加进去。分析与思路:首先,单个字符的元素是比较容易判断的,然而,对于关键字,标识符,数字这种就有点麻烦,包含多个字符的。我的思路是,因为多个字符的三种情况的一个元素里面是不可能含有分界符运原创 2017-10-12 14:52:53 · 4255 阅读 · 0 评论 -
算法练习(13):Regular Expression Matching
题意:实现一个正则匹配函数,判断输入的正则式和输入的字符串是否匹配,规则如上图分析与思路:这道题要是没有*,就是个非常容易的题目,但是加了个*,就要特殊处理了,因为*是不限制个数的,所以很容易就想到了循环或者递归来处理这个情况。而我的想法是用递归来实现的,把匹配完的部分都截掉,这样就可以明确了*的位置,也就是下标1的位置,这样就需要判断首字符了。*的处理方法呢,我分为0个和多个两种情况,多个的原创 2017-10-12 14:10:43 · 276 阅读 · 0 评论 -
算法练习(19):Jump Game II
题意:如题,和Jump Game II差不多,只不过这次是假定都能到达最后下标,求出最少次数。分析与思路:这次还是用贪婪算法,不过要记录每个位置的最先能到达这里的上一个位置,所以只有在每次最远到达位置(far)能更新时,拓展部分(旧far到新far之间)的位置的上一跳位置就要记录一下,这样,就能保证到达每个位置的路径都是最少次数的。代码:class Solution {public:原创 2017-10-19 21:11:50 · 272 阅读 · 0 评论