2012年12月25日

摘要: 第一题:求N!末尾有多少个0.解题思路:通过判断阶乘中每一个数包含的2和5的个数,取其中更小的那个数即为末尾0的个数。 更进一步观察发现,2的个数肯定比5的个数多,所以,只需要求5的个数。。。第二题:求N!的二进制表示中最低位1的位置。解题思路:其实,就是求阶乘结果中2的个数+1。上述两题都转化为求N!的质因数的个数,一种简单的思路就是循环获得小于等于N的每一个数所包含的质因数x的个数,最终得到的总数即为所求。第二种方法是:N!中要得到包含某个数k的个数,其实相当于[N/k] +[N/k2] +[N/k3] +[N/k4] +...。原理:首先,[N/k]等于1,2,3,...,N... 阅读全文
posted @ 2012-12-25 16:41 小龙人2012 阅读(252) 评论(0) 推荐(0) 编辑

2012年12月24日

摘要: 求节点最大距离,还是可以分解为求根节点最大距离和求它的左右子树的最大距离。这一题中,由于只需要得到最大距离,所以在每一步中获得当前根节点的最大距离,并与全局变量MaxLen比较即可;貌似这题没有什么重叠子问题,直接递归即可。正如书中所说,弄清楚递归的边界条件和每一步递归的顺序,对于递归过程做到心中有数,同时想好设置什么样的参数和返回值等以使得解决方法最简单,即可轻松实现这一类递归问题;int MaxLen = 0;int MaxDistance(const Node *root){ if (root->lchild == NULL && root->rchild = 阅读全文
posted @ 2012-12-24 00:21 小龙人2012 阅读(197) 评论(0) 推荐(0) 编辑

2012年12月22日

摘要: 通过一棵树的先序和中序的遍历结果,重建这棵树。解题思路:还是递归,每一次在先序字符串中获得当前的根节点后,在中序字符串中找到它的位置,然后计算它的左子树和右子树对应的字符串开始与结束位置,并继续求它的左子树和右子树。重点是找清楚每次获得两个字符串的起始和结束位置!结束条件是开始位置大于结束位置,返回NULL;只有当节点的信息不重复时,才能正确地求得一棵的树。#include<iostream>#include<string>#include<vector>#include<malloc.h>using namespace std;typedef 阅读全文
posted @ 2012-12-22 22:33 小龙人2012 阅读(248) 评论(0) 推荐(0) 编辑
摘要: 使用gdb调试程序时,当发现问题想要修改源代码时,可以直接在用vim打开的源代码中编辑,并使用vim 的 :!g++ -g -o xxx.out xxx.cpp 命令重新生成(一定要记住需要重新编译,否则你在gdb中单步调试或者list看到的源代码已经改过来了,但是事实上并没有编译。)。然后在gdb中输入r即可重新运行,这里不需要从gdb中退出,之前设置的断点也可以继续使用。 阅读全文
posted @ 2012-12-22 22:21 小龙人2012 阅读(910) 评论(0) 推荐(0) 编辑
摘要: 解题思路:一开始想到递归,发现用递归很难保证节点的访问顺序。(递归对于先,中,后序遍历都有效,但是对于层次遍历似乎没有找到可行的方法)按照层次遍历二叉树的做法,通常用一个队列来保证节点按照先入先出的顺序来。这题的关键是如何在使用队列时确定当前所处的层次,以保证输出的每一层节点为一行。解决办法是设置两个游标cur和last,cur指向当前处理的节点,last指向当前层的最后一个节点的下一个位置。每次内循环都是输出一整层的节点,并将它们的子节点入队列。void PrintNodeByLevel(const Node *root){ vector<const Node*> vec; ve 阅读全文
posted @ 2012-12-22 19:10 小龙人2012 阅读(142) 评论(0) 推荐(0) 编辑

2012年12月21日

摘要: 问题本身很简单,考虑扩展问题:如果链表有环的话,又或者求解相交的第一个节点,个人认为都是采用计数的方法比较适合。也就是说设置一个hash表,记录指针指向的地址,无论求是否有环或者找到第一个相交的节点都可以。唯一缺点是需要额外的空间。书上提到的第三个解法有些需要注意的地方:它不是一个线程安全的,因为在这个过程中,它改变的链表的结构(虽然最终会修改回来)。而且这种比较类型的功能函数一般都不应该更改它的值。LNode* JudgeIntersect(LNode *la, LNode *lb){ LNode *p = la, *q = lb; while(p != NULL){ ... 阅读全文
posted @ 2012-12-21 14:39 小龙人2012 阅读(159) 评论(0) 推荐(0) 编辑
摘要: 主要思想为递归求解,每一次都需要计算三种情况下的最小值。需要注意的是几个条件:1、一旦begin>end,则结束当前递归,返回值为0;2、如果当前pAbegin == pBbegin,则两个指针都直接跳到下一个字符;这里给出用map保存递归过程每一次的指针状态,以避免重复的递归计算(除结束状态,因为结束状态的计算无需递归,开销更小);定义MapCmp访函数做为排序准则时,需要注意满足三个条件,即strict weak ordering(反对称,可传递,非自反(这个容易遗忘));#include<iostream>#include<string>#include&l 阅读全文
posted @ 2012-12-21 00:33 小龙人2012 阅读(146) 评论(0) 推荐(0) 编辑

2012年12月19日

摘要: 在《权威指南》p68页中,作者提到:通过建立索引{date : -1, user : 1},这样,就可以保证最后几天更新的索引全部保存在内存中,这样,每个人的最新动态都将查询很快。但是,这样的索引结构对于查询:db.test.find ({"user":1} ).sort("date":-1).limit(n)这个操作来说,问题是很大的。经过explain测试,要查询上面这个语句,一定要建立索引为 [ (user , 1) , (date,-1) ] ,这样,无论你查询的是哪一个,同步查询多个用户,查询第多少页,都是非常快的。也是stackoverflo 阅读全文
posted @ 2012-12-19 23:05 小龙人2012 阅读(140) 评论(0) 推荐(0) 编辑
摘要: 主要思路就是递归遍历所有可能的单词;设置一个数字对应字符集的对照表vec,并设置一个数组count保存每个数字的字符集大小(为了避免在递归中使用str.length()所带来的性能开销);数组number保存输入的数字;设置一个flag数组,可以保存当前每一个数字所对应的字母下标;index记录当前处理到的数字在数组中的下标;n为输入号码长度;内存开销基本只有递归的开销比较大;(书上的循环解法真心没看懂,可是作者竟然说循环比递归简单,我了个擦。mark下)#include<iostream>#include<string>#include<vector>us 阅读全文
posted @ 2012-12-19 22:50 小龙人2012 阅读(223) 评论(0) 推荐(0) 编辑
摘要: 简单的方法就是直接将第一个字符串自加,然后查找其中是否有其子串。注意:find方法返回的是string::npos,它一般是-1,但是在我的机器上,是无符号数4294967295。1 #include2 #include3 using namespace std;45 bool offcon(const string &s1, const string &s2){6 string s3 = s1 + s1;7 cout<< s3 << endl;8 cout<< s2 << endl;9 cout<< s3.find( 阅读全文
posted @ 2012-12-19 19:31 小龙人2012 阅读(118) 评论(0) 推荐(0) 编辑

导航