2013年1月7日

摘要: (这个题目让我想到泡泡堂这个游戏,呵呵!)解题思路:一开始想的是边遍历,边设置行和列为0并标记.这个方法的错误之处在于:这个过程会导致你无法找到所在行列的其它为0的元素。所以,只能先遍历矩阵,找出所有的0元素所在的行和列,并记录下来。之后,可以通过两种方式更新矩阵A,1、通过遍历所有存在0元素的行、列,并置矩阵A中该行、列为0;时间复杂度为M×i+N×j(i,j为存在0的行和列个数)2、再次遍历矩阵A,并判断A[i][j]的下标i或j是否在之前记录下来的存在0的行或列中,时间复杂度为M×N;这是第一种更新矩阵解法#include<iostream>#i 阅读全文
posted @ 2013-01-07 22:00 小龙人2012 阅读(1312) 评论(0) 推荐(0) 编辑
摘要: 思路:将一个正方形矩阵看做一层层的,每一层进行旋转。其实这题的解法和“数组循环右移K位”的杂技解法有些类似,只是这题复杂在每一层的下标的确定,而右移字符串则是复杂在循环链的计算和确定。void rotate(){ int i,j,k; int count=0; for (i=0;i<(int)(N/2);i++){ for (j=i;j<N-i-1;j++){ int temp = x[i][j]; x[i][j] = x[N-1-j][i]; ... 阅读全文
posted @ 2013-01-07 20:38 小龙人2012 阅读(228) 评论(0) 推荐(0) 编辑
摘要: malloc和free是在动态分配内存空间和释放时用到的。使用malloc和free通常是在定义一些链表或者指针数组等动态结构会用到,而malloc时,操作系统也会做一些工作,主要是从空闲堆中分配一块空间,而且,这块空间还包括了该空间块大小等信息,以便释放时用到。这大概也是一个malloc对应一个free这句话的一层意思。之前想到,如果我分配的空间现在不需要使用这么大,就像原字符串被截断了这种情况该怎么办呢?目前想到的只有重新分配一个新的空间,然后把需要保留的copy到这里,释放原空间,或者是不管原空间大小,只需要正确设置结束符即可。不知道c++string的resize是怎么实现的?有时间去 阅读全文
posted @ 2013-01-07 13:56 小龙人2012 阅读(198) 评论(0) 推荐(0) 编辑
摘要: 注意此题不是指删除连续的重复字符,而是所有重复的字符。两种思路:1、不用额外的空间。直接在当前字符串上更改,采用类似直接插入排序的方法,将字符串前一部分设为新的字符串,依次判断后续的每一个字符是否在新的字符串中,没有出现则将其添加到新的字符串末尾,否则说明重复,判断下一个字符。最后,将新的字符串末尾置为结束符'\0';(如果是c++的std::string,应该用resize,因为string不通过结束符判断字符串,而是通过内置一个长度判断。)2、使用额外的空间,则可以考虑使用一个set记录已经出现过的字符,或者这里可以使用数组bool hit[256],这是因为字符最多就25 阅读全文
posted @ 2013-01-07 13:31 小龙人2012 阅读(180) 评论(0) 推荐(0) 编辑

2013年1月6日

摘要: 给定N个数组,将其向右循环移动K位。此题在编程珠玑上曾经见过,先写个例子观察:abcdefg,向右移动3位 ->efgabcd。最简单的思路是循环将整个数组移动k位(这里k可以转化为k%=n,因为循环移位整个数组可以看成一个环),但是时间复杂度较高。然后,通过上述例子发现,循环移位后,数组的两个部分仅仅是移动了位置,其它不变,所以,可以用一个临时数组缓存较小的一部分,然后将较大的一部分移动到移位后的位置,再将较小的部分加入。但是,如果数组很大,可能空间复杂度会较大。第三个方法是通过对两部分分别逆序,再整个逆序达到效果:1、逆序abcd:abcdefg -> dcbaefg;2、逆序 阅读全文
posted @ 2013-01-06 11:10 小龙人2012 阅读(343) 评论(0) 推荐(0) 编辑

2012年12月27日

摘要: 解题思路:设数组为1,-1,2,-3,4,-5,6,-7从后向前迭代:-7首先直接放入临时数组(-7,1),1代表长度为1; 6,比-7大,所以不能和-7组合为递增序列,同时6肯定优于-7,所以置换为(6,1); -5比6小,可以和6组合为递增序列,(-5,2),(6,1); 4比6小,可以和6组合为递增序列,同时,4比-5大,所以置换为(4,2),(6,1); -3比6小,可以组合,同时,-3比4小,也可组合,添加,(-3,3),(4,2),(6,1); 2比6小,可以组合,2比4小,也可组合,2比-3大,置换(2... 阅读全文
posted @ 2012-12-27 15:49 小龙人2012 阅读(309) 评论(0) 推荐(0) 编辑

2012年12月26日

摘要: 从一个数组中找出两个数字,让这两个数字之和等于一个给定值。解题思路:第一印象是循环查找,从第一个数开始,取所有其后面的数与其相加,并判断是否为给定值。此复杂度为O(n2).这种复杂度为O(n2)的解法,又是在一个无序的数组中,可以尝试先将其排序,再看排序后是否可以简化循环过程。下面是一个排序后的数组:1,4,5,6,7,8,9想要找相加和为N,则设置两个指针指向两端(p指向第一个,q指向最后一个),如果当前所指两个数相加大于N,则说明不可能还有在q所指元素之后与q所指元素相加会小于等于N,所以指针q向前移,如果两个数相加小于N,说明不可能还有数在指针p所指元素之前与当前所指元素相加会大于等于N 阅读全文
posted @ 2012-12-26 19:16 小龙人2012 阅读(268) 评论(0) 推荐(0) 编辑
摘要: 解题思路:一种是存储递归过程中已经计算过的值,另一种是通过递推关系式;这是第二种方法:F(n) = F(n-1) + F(n-2)F(n-1) = F(n-2) + F(n-3)...F(4) = F(3) + F(2)F(3) = F(2) + F(1)F(2) = F(1) + F(0)可以看出自底向上,每一次求解的两个值都包含在前一次的公式中,用代码写就相当于:int t;t = a;a = a + b;b = t;每次只需要用一个临时变量保存第一个值,然后将其做为下一次迭代的第二个值就可以了。int Fibonacci(int n){ if (n <= 0) ret... 阅读全文
posted @ 2012-12-26 17:01 小龙人2012 阅读(310) 评论(0) 推荐(0) 编辑
摘要: 想要得到N个数中最大的K个数,典型的思路就是设置一个数组arr[K],然后遍历N个数,判断当前数和数组arr[k]中最小的数,如果它大于数组中最小的数,则置换。在这个数组中寻找最小的数,如果无序的话,很明显复杂度即为O(K),如果排序的话,维护一个有序数列,并且每次都是取该序列最小值进行比较,就自然地想到了小根堆了。下面是使用c++的stl中的堆算法实现的代码,由于stl只支持四种算法:push_heapPush element into heap range(function template)pop_heapPop element from heap range(function temp 阅读全文
posted @ 2012-12-26 11:10 小龙人2012 阅读(204) 评论(0) 推荐(0) 编辑

2012年12月25日

摘要: 直接用辗转相除法。即设f(x,y)为x,y最大公约数,则f(x,y) = f(y, x%y).主要的思路比较清晰,在这里记录一下辗转相除法的证明,就当找一找高中的感觉吧。。设:x,y(x>=y)最大公约数是c,证明x,x%y的最大公约数同样是c。1、x = k*y + r; r = x%y.2、设x = mc,y = nc;3、由1,2得:mc=knc +r,即:r=(m-kn)c;4、此时,只需证明m-kn与n是互素即可。反证:设m-kn与n非互素,则m-kn = ed,n =qd, => m = kn+ed = kqd+ed = (kq+e)d, 又x =mc = (kq+e) 阅读全文
posted @ 2012-12-25 22:16 小龙人2012 阅读(119) 评论(0) 推荐(0) 编辑

导航