随笔分类 - 算法设计类
摘要:对于这个问题,首先按照《编程之美》中的分析对这个问题进行一定的简化。从2n个数中找n个元素,有三种可能:大于Sum/2,小于Sum/2以及等于Sum/2。而大于Sum/2与小于等于Sum/2没区别,故可以只考虑小于等于Sum/2的情况。动态规划第一步,分析子问题:这里我们用一个三维数组F[][][]表示子问题,F[i][j][k]表示前i个元素中选取j个元素,使得其和不超过k且最接近k。这个子问题可以根据第i个元素是否选择来进行分析:如果我们想回溯找到一组合理的分割方式,那么在子问题的求解过程中,就要记录有效的路径,这样我们再用一个三维数组path[][][]来记录。伪代码如下所示: 1 F[
阅读全文
摘要:计算字符串的相似度,这个问题是《编程之美》中的一个经典问题,问题的解决其实应该使用动态规划来解决,在《编程之美》中其实已经给出了该问题的子问题,不过最终用了递归的方法来实现,这使得算法有许许多多的重复计算,算法的复杂度达到了指数级。本文对该问题重新分析,用动态规划的方法来实现,是复杂度降为O(m*n)(其中m、n分别为两个字符串的长度)。对于一个动态规划问题,那么解决这个问题的第一步就是找到子问题。这里利用《编程之美》中的分析方法:不难看出,两个字符串的距离肯定不超过它们的长度之和(我们可以通过删除操作把两个串都转化为空串)。虽然这个结论对结果没有帮助,但至少可以知道,任意两个字符串的距离都是
阅读全文
摘要:之前学习了动态规划中最基本的问题,最长公共子序列,具体解法,见前前一篇博客:http://www.cnblogs.com/liyukuneed/archive/2013/05/22/3090597.html本篇博客要继续解决一个升级的问题——最长递增子序列问题定义:给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱)。例如:给定一个长度为6的数组A{5, 6, 7, 1, 2, 8},则其最长的单调递增子序列为{5,6,7,8},长度为4.解法一:最长公共子序列法:仔细思考上面的问题,其实可以把上面的问题转化为求最长公共子序列的问题。原数组为A{5, 6, 7,
阅读全文
摘要:最长公共子序列是一个很经典的动态规划问题,最近正在学习动态规划,所以拿来这里再整理一下。这个问题在《算法导论》中作为讲动态规划算法的例题出现。动态规划,众所周知,第一步就是找子问题,也就是把一个大的问题分解成子问题。这里我们设两个字符串A、B,A = "a0, a1, a2, ..., am-1",B = "b0, b1, b2, ..., bn-1"。(1)如果am-1 == bn-1,则当前最长公共子序列为"a0, a1, ..., am-2"与"b0, b1, ..., bn-2"的最长公共子序列与am-1的
阅读全文
摘要:前些天,听一位找到工作的大神谈起面试题,突然说起一道关于排序二叉树的题,题目要求找出比给定值小,但是最接近给定值的节点。身为小白的我,看到这个题还是比较迷茫的,回来之后好好思考了一下,经过查资料,发现其实就是问查找前驱和后驱的问题。下面是我自己实现的查找二叉树的系列操作,分享给大家,其中关于前驱后驱的问题,主要是参考算法导论的做法,现在网上的博客似乎这个讲的不是很清楚,所以具体的大家可以看算法导论相关部分。 1 #include <stdio.h> 2 3 typedef struct node 4 { 5 int m_nValue; 6 struct node ...
阅读全文
摘要:原帖地址:http://www.cppblog.com/humanchao/archive/2008/04/17/47357.html有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一环。问题:1、如何判断一个链表是不是这类链表?2、如果链表为存在环,如何找到环的入口点?解答:一、判断链表是否存在环,办法为:设置两个指针(fast, slow),初始值都指向头,slow每次前进一步,fast每次前进二步,如果链表存在环,则fast必定先进入环,而slow后进入环,两个指针必定相遇。(当然,fast先行头到尾部为NULL,则为无环链表)程
阅读全文
浙公网安备 33010602011771号