随笔分类 - 算法
摘要:转自: http://www.cnblogs.com/codingmylife/archive/2012/10/21/2732980.html首先,排序算法的稳定性大家应该都知道,通俗地讲就是能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。在简单形式化一下,如果Ai = Aj,Ai原来在位置前,排序后Ai还是要在Aj位置前。 其次,说一下稳定性的好处。排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。基数排序就 是这样,先按低位排序,逐次按高位排序,低位相同的元素其顺序再高位也相同时是不会改变的。另外,
阅读全文
摘要:老题了。既然又写了遍就记录下#include <iostream>#include <cassert>using namespace std;int maxSum(int* arr, int length){ assert(arr!=NULL); assert(length >=0); int sum = 0; int max = 0; for(int i=0; i<length; i++) { sum = sum + arr[i]; if(sum < 0) sum = 0; if(max < ...
阅读全文
摘要:将字符串进行如下反转: 如果字符串为 how are you则反转为 you are how也就是单词反转,但是每个单词内部不变。两个解法,第一个是根据空格把每个单词弄出来,保存起来,然后反转就好了第二种,先反转整个句子,之后,再对每个单词在进行一次反转。代码如下:#include <iostream>#include <string>#include <cassert>using namespace std;void reverseRange(char* str,int begin,int end){ assert(str != NULL); assert
阅读全文
摘要:题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。主要是参考了一下两篇文章:http://blog.csdn.net/qitian0008/article/details/8042558http://www.cnblogs.com/eric-blog/archive/2012/05/03/2481510.html其中常规的方法,就是用一个i从左到右进行遍历,当i指向某个值的时候,以i为中心,逐个比较左右两个的字符是否相等。这样就可以找到一个回文,以及他的长度。但是,这样做的时候,是有重复计算
阅读全文
摘要:1、如何判断一个链表是不是有环? 2、如果链表为存在环,如果找到环的入口点?这个算是一个比较老的题目了,之前就看到过,一般通用的做法就是弄两个指针,一个走得快一点,一个走得慢一点。一般是弄一个走一步,一个走两步。这样如果他们相遇,则说明有环。那么在有环的基础上,怎么找到这个环的入口呢,一般网上也会给出解释,可能是我的理解力比较底,网上的解释中,总是用移动了s步,又是长度的,总是弄的我很晕,于是,给出我自己的解释好了,所有的都用移动了多少步来说明。走一步的指针叫slow,走两步的叫fast。相遇的时候,slow共移动了s步,fast共移动了2s步,这个是显而易见的。定义a如下: 链表头移动a步.
阅读全文
摘要:题目:有一个复杂链表,其结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任一结点或者NULL。其结点的C++定义如下:struct ComplexNode{ int value; ComplexNode* pNext; ComplexNode* pSibling;}; 请完成函数ComplexNode* Clone(ComplexNode* pHead),以复制一个复杂链表。 思路: 一般复制一个简单链表就这么遍历一遍就好了,这个复杂链表,比简单链表多的地方就在于多了一个sibling的指针,也就是说在建立完简单链表之后,如何在新的...
阅读全文
摘要:题目:用递归颠倒一个栈。例如输入栈{1, 2, 3, 4, 5},1在栈顶。颠倒之后的栈为{5, 4, 3, 2, 1},5处在栈顶。个人并不觉得这道题设计的有多么好,纯粹就属于没事卖弄技巧的那种,蛋疼的用递归来颠倒一个栈,又浪费时间又浪费空间。解法的思想其实很简单,那么就是你要我颠倒栈,那么我就先把第一个元素保存了,然后弹出其余所有的元素,然后把第一个元素压进去,然后按原来的顺序,压入被弹出的元素,得到的就是 2 3 4 5 1, 2在栈顶,接着用对于前四个,用同样的方法,最后终于颠倒了。void reverseStack(stack<T>& s){ int count
阅读全文
摘要:题目的意思很简单,比如说有数组[1,6,9,2,1,5,15,20],那么满足上述条件的元素为1,15,20。暴力的方法就是从左到右进行遍历,到达某个数字后,在从0开始遍历到当前下标,找出最大的,再从当前下标遍历到尾,找出最小的,然后根据题意比较一下,这个算法为O(n^2)。比较简单的算法就是利用一下额外的空间,保存一下,每个元素右侧的最小值,或者左侧的最大值,在反向遍历一次。举个例子。就如[1,6,9,2,1,5,15,20],如果我们要找到该数组右侧的最小值,则从后向前遍历,20开始,20的右侧的最小值为20,之后15,15右侧的最小值为15,之后5,最小值为5,之后1,最小值为1,那么新
阅读全文
摘要:题目:已经两个已经排好序的数组,找出两个数组合起来的中间大的数字。要求算法复杂度尽可能低。如:x数组:1,7,9,10,30 y数组:3,5,8,11 则中间大数为:8这个题目看似简单,不过要处理起来还是有很多小细节需要注意的。主要思想就是用两个指针同时遍历两个数字,如果第一个数组的值比第二个的小,就第一个数组向前走,否则第二个数组向前走。如果两个的下标等于中间的下标了,那么输出,如果一个数组遍历完成了,还没有到达中间的下标,则说明中间值在另个数组中,标号为 中间下标减去走完的数组元素总数。代码如下: #include "stdafx.h"#include <iost
阅读全文
摘要:传说是一道腾讯的面试题题目如下: 根据上排给出十个数,在其下排填出对应的十个数 要求下排每个数都是先前上排那十个数在下排出现的次数。 上排的十个数如下: 【0,1,2,3,4,5,6,7,8,9】没错,题目就是只有这么一点。思考过程:第一排的数字: 0 1 2 3 4 5 6 7 8 9 如果下一排全是0的话,那么,0下面(即指第二排,之后类似)就应该是10,这样,0下的的数字就应该是9,那么9下面就应该是1,那么1下面就应该是1,那么0下面就成了7,这样9下面的1就不应该存在了,反而7下面是1,这样1下面是1,7下面也是1,这样1下面就应该是2,不过这个又带来一个问题就是,1下面是2就是错的
阅读全文
摘要:原文地址: http://blog.csdn.net/wcyoot/article/details/6428248貌似原文说的不是太详细,表示理解之后,在这里重新解释下,同时感谢原文博主提供了这么多题目以及解答。题目:4个人在晚上过一座小桥,过桥时必须要用到手电筒,只有一枚手电筒,每次最多只可以有两人通过, 4个人的过桥速度分别为1分钟、2分钟、5分钟、10分钟,试问最少需要多长时间4人才可以全部通过小桥?抽象: N个人过桥,每个人过桥需要的时间为ti(1<=i<=N).每次最多两个人过桥,并且还要回来一个。求最快过桥时间。输入:每人过桥时间数组,人数(数组元素个数)。输出:最快时
阅读全文
摘要:题目:输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。例如 输入整数22和如下二元树 10 / \ 5 12 / \ 4 7则打印出两条路径:10, 12和10, 5, 7。先序遍历树即可得到结果。算法: PrintPath(TreeNode* pRoot, int sum, const int target) 用来计算,sum为栈中的元素的和,target为目标值。到达一个节点之后计算当前节点和sum的和,如果为target,输出路径返回,如果大于target,则直接...
阅读全文
摘要:原文地址: http://blog.csdn.net/wcyoot/article/details/6428297题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。 比如将二元查找树 10 / \ 6 14 / \ / \ 4 8 12 16转换成双向链表4=6=8=10=12=14=16。很明显我们可以知道 中序遍历 一遍二叉查找树就可以得到一个递增的序列。同样,只要中序遍历一下儿茶查找数,调整一下左孩子指针和右孩子指针的指向,就可以得到一个双向链表。代码中的pListHead和pListLast的初始值都是NULL,其中...
阅读全文
摘要:没啥太多技巧,反转就好了。单链表的时候要注意,while中不能将pCur的next指向NULL,否则的话,pNext的next就白指了。#include "stdafx.h"#include <iostream>#include<cstring>#include <vector>#include <assert.h>using namespace std;struct ListNode{ int m_key; ListNode* next;};void createList(ListNode* &pHead){ pHe
阅读全文
摘要:原文地址: http://blog.csdn.net/jackyliujin/article/details/7581727情况1. 节点只有left/right,没有parent指针,root已知情况2. root未知,但是每个节点都有parent指针情况3. 二叉树是个二叉查找树,且root和两个节点的值(a, b)已知--------------------------------------------------------------------------------虽然情况一是第一个情况,但是看上去比较复杂,我们放到最后来说,先从第二个情况开始说。 10 /\ 6 14 /\
阅读全文
摘要:题目:输入n个整数,输出其中最小的k个。例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。如果这些数字,是放在数组中给出的话,直接建立小顶堆,然后输出前k个就好了。 时间复杂度 kLog(n),建立堆log(n),共建k次void heapAdjust(int* a,int s, int m){ int temp = a[s]; for(int j=2*s+1; j<=m; j=j*2+1) { if(j<m && a[j] > a[j+1]) j++; if(temp<=a[j]) ...
阅读全文
摘要:#include "stdafx.h"#include <iostream>#include <assert.h>using namespace std;//对于a来说,除了a[s]之外均满足大顶堆的定义// 该函数将下标 s到m 调整为大顶堆void heapAdjust(int* a,int s, int m){ int temp = a[s]; // 下标从0开始,则两个孩子分别为 2*i+1 和 2*i+2 for(int j=2*s+1; j<=m; j=j*2+1) { // 执行完成后j中保存了两个孩子中较大的孩子的下表 // .
阅读全文
摘要:题目:输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。链表结点定义如下:struct ListNode { int m_nKey; ListNode* m_pNext; };两个方法,第一个先遍历,获得链表总共的长度,这样就知道从head到达倒数第k个需要移动多少次,从头在移动一遍。第二个,两个指针,第二个比第一个多移动k次之后,两个指针再一起移动,这样两个指针之间始终有k个距离,当第二个指针移动到NULL的时候,第一个指针所指向的就是倒数第K个。代码如下:template <typename T>struct ListNode{ T m_k...
阅读全文
摘要:题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。这题貌似也是一道很常见的题目,主要思路就是如下的这段话:我们以三个字符abc为例来分析一下求字符串排列的过程。首先我们固定第一个字符a,求后面两个字符bc的排列。当两个字符bc的排列求好之后,我们把第一个字符a和后面的b交换,得到bac,接着我们固定第一个字符b,求后面两个字符ac的排列。现在是把c放到第一位置的时候了。记住前面我们已经把原先的第一个字符a和后面的b做了交换,为了保证这次c仍然是和原先处在第一位置的a交换,我们
阅读全文
摘要:传说这是一道知名外企的笔试题但是看了一些文章,都只是单纯的转了那个算法,弱弱的说一句,那个算法中把'\0'写成了'/0',会导致在while ('/0' != *pTemp) { hashTable[*pTemp] = 1; ++ pTemp; } 这一步的时候,一直循环下去,直到系统中断。不过调试的时候发现了一个很有意思的事情,就是之前pTemp之前是指向aeiou,这就是传入的第二个参数,当遍历完这个参数之后,pTemp会继续指向栈中的下一个地址,也就是第一个参数they are students的地址,这个...
阅读全文

浙公网安备 33010602011771号