随笔分类 -  【算法】

摘要:一,题目 给定链表的头指针和一个结点指针,在O(1)时间删除该结点。链表结点的定义如下:struct ListNode{int m_nKey;ListNode* m_pNext;};函数的声明如下: void DeleteNode(ListNode* pListHead, ListNode* pToBeDeleted);二,分析 这是一道广为流传的Google面试题,能有效考察我们的编程基本功,还能考察我们的反应速度,更重要的是,还能考察我们对时间复杂度的理解。在链表中删除一个结点,最常规的做法是从链表的头结点开始,顺序查找要删除的结点,找到之后再删除。由于需要顺序查找,时间复杂度自然就是O( 阅读全文
posted @ 2012-08-23 23:10 MXi4oyu 阅读(288) 评论(0) 推荐(0)
摘要:一,题目 用C++设计一个不能被继承的类。二,分析 在Java中定义了关键字final,被final修饰的类不能被继承。但在C++中没有final这个关键字。 首先想到的是在C++中,子类的构造函数会自动调用父类的构造函数。同样,子类的析构函数也会自动调用父类的析构函数。要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数。那么当一个类试图从它那继承的时候,必然会由于试图调用构造函数、析构函数而导致编译错误。 可是这个类的构造函数和析构函数都是私有函数了,我们怎样才能得到该类的实例呢?通过定义静态来创建和释放类的实例。三,实现 下面是一个单利模式的实现#include < 阅读全文
posted @ 2012-08-23 22:31 MXi4oyu 阅读(240) 评论(0) 推荐(0)
摘要:一,题目 输入一个链表的头结点,从尾到头反过来输出每个结点的值。链表结点定义如下:struct ListNode{ int m_nKey; ListNode* m_pNext;};二,分析 解法一:把链表中链接结点的指针反转过来,改变链表的方向。然后就可以从头到尾输出了。参考 解法二:从头到尾遍历链表,每经过一个结点的时候,把该结点放到一个栈中。当遍历完整个链表后,再从栈顶开始输出结点的值,此时输出的结点的顺序已经反转过来了。该方法需要维护一个额外的栈,实现起来比较麻烦。 解法三:递归本质上就是一个栈结构。于是很自然的又想到了用递归来实现。要实现反过来输出链表,我们每访问到一个结点的时候,先递 阅读全文
posted @ 2012-08-23 22:08 MXi4oyu 阅读(174) 评论(0) 推荐(0)
摘要:一,题目 某队列的声明如下:template<typename T> class CQueue{public: CQueue() {} ~CQueue() {} void appendTail(const T& node); // append a element to tail void deleteHead(); // remove a element from headprivate: T m_stack1; T m_stack2;};二,分析栈:后入先出,插入删除在栈顶操作 队列:先入先出,插入... 阅读全文
posted @ 2012-08-23 21:50 MXi4oyu 阅读(215) 评论(0) 推荐(0)
摘要:一,题目 如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,则字符串一称之为字符串二的子串。 注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中。 请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。 例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子串,则输出它们的长度4,并打印任意一个子串。二,分析 求最长公共子串(Longest Common Subsequence, LCS)是一道非常经典的动态规划题。 LCS问题的性质:记Xm={x0, x1,…xm-1}和Yn={y0,y1,…,yn. 阅读全文
posted @ 2012-08-22 23:53 MXi4oyu 阅读(214) 评论(0) 推荐(0)
摘要:一,题目 输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)。二,分析 如果不考虑时间复杂度,最简单的思路应该是从头扫描这个数组,每碰到一个偶数时,拿出这个数字,并把位于这个数字后面的所有数字往前挪动一位。挪完之后在数组的末尾有一个空位,这时把该偶数放入这个空位。由于碰到一个偶数,需要移动O(n)个数字,因此总的时间复杂度是O(n2)。改进:要求的是把奇数放在数组的前半部分,偶数放在数组的后半部分,因此所有的奇数应该位于偶数的前面。也就是说我们在扫描这个数组的时候,如果发现有偶数出现在奇数的前面,我们可以交换他们的顺序, 阅读全文
posted @ 2012-08-22 22:10 MXi4oyu 阅读(229) 评论(0) 推荐(0)
摘要:递归求解思路:1) 每个元素依次放到首位,然后对其余元素递归2) 当当前元素到达末尾的时候,输出该序列关键是:每个元素交换完,之后要交换过来。每个元素依次放到首位,for(inti=currentIndex;i<=n;++i){swap 从i+1递归 swap }#include<stdio.h> #include<stdlib.h> #define SWAP(x,y,t)((t)=(x),(x)=(y),(y)=(t)) int score=0; void perm(int *list,int i,int n) { int j,temp; if(i==n)... 阅读全文
posted @ 2012-08-22 22:08 MXi4oyu 阅读(215) 评论(0) 推荐(0)
摘要:一,题目 输入一个正数n,输出所有和为n连续正数序列。 例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以输出3个连续序列1-5、4-6和7-8。二,思路 解法一:连续正序列,不包含n本身。所以子序列中最大元素为 n/2+1 求出到前 i个元素和保存到b数组中,然后遍历数组b ,i>j 时,求b[i] –b[j] ==n。如果等于则输出 j+1 到 I 的序列。 时间复杂度:O(n^2) #include <iostream> using namespace std; void print(int a[],int j,int... 阅读全文
posted @ 2012-08-21 10:20 MXi4oyu 阅读(202) 评论(0) 推荐(0)
摘要:一,题目 如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)二,解答 关键:哈希表,空间复杂度O(1)中1的含义(只要是常量就可以) 看上去似乎任何已知的算法都无法做到,如果谁做到了,那么所有的排序方法:QuickSort,ShellSort,HeapSort,BubbleSort等等等等,都可以扔掉了,还要这些算法干吗阿?不过实际上,在数字范围有限制的情况下,是有一个这样的算法的,只需要用一个数组记录每个数字出现次数就可以了。 假定你的数字范围在0到65535范围之内,定义一个数组count[65536](这个空间是常量,和n无关,所以是O(1) ),初值全部为0。 那么假设有 阅读全文
posted @ 2012-08-21 00:25 MXi4oyu 阅读(268) 评论(0) 推荐(0)
摘要:一,题目 一个数组是由一个递减数列左移若干位形成的,比如{4,3,2,1,6,5}是由{6,5,4,3,2,1}左移两位形成的,在这种数组中查找某一个数。二,分析 1)在此序列不断二分的过程中,由于原序列是一个递减序列经过旋转得到的,将它从任何位置分开,都会得到两个序列, 其中一个是递减序列 另一个可以通过一个递减序列通过旋转得到。 2)这样在不断地二分查找时,我们处理的序列子片段要么就是一个旋转后递减序列,要么就是一个纯递减序列, 3)无论是前者还是后者,在继续分成两个片段时,至少有一个纯递减序列(可能两个都是,如果之前的序列片段就是纯递减序列的话)。 4)这样我们可以保证能找到一个片... 阅读全文
posted @ 2012-08-21 00:19 MXi4oyu 阅读(387) 评论(0) 推荐(0)
摘要:一,题目 求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2} 求一个数组的最长递增子序列 比如{1,-1,2,-3,4,-5,6,-7}的最长递减子序列为{1,2,4,3,6} 二,递增序列长度求解方法 解法一: 时间复杂度为 o(n^2) 遍历数组序列,每遍历一个数组元素,则求序列到当前位置 最长的递增序列数,用temp[i]存储。 注意,当前的最长递增子序列受已经遍历的最长递增子序列影响,从序列头 再遍历到当前位置的前一个位置,挨个... 阅读全文
posted @ 2012-08-20 23:35 MXi4oyu 阅读(194) 评论(0) 推荐(0)
摘要:一,题目 四对括号可以有多少种匹配排列方式?比如两对括号可以有两种:()()和(())二,解答 解法一:左右括号成一对则抵消 可以将左括号看成1右括号看成 -1,然后对8个数进行全排列 对每个排列判断,是否符合条件,逐个相加,sum>=0直到遍历完该序列,符合条件则count++ 如果出现sum<0则失败 解法二:采用八位bit,从0000 0000 到 1111 1111遍历,遇到0加 -1遇到1加 1 如果加完该序列所有位等于0,且递加过程中sum始终大于零则符合条件三,源码#include<iostre... 阅读全文
posted @ 2012-08-20 18:54 MXi4oyu 阅读(255) 评论(0) 推荐(0)
摘要:一,对于一个整数对于一个整数矩阵矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一,现给出一正数矩阵,判断其是否能够由一个全零矩阵经过上述运算得到。 分析:对任意一个位置,他的值不大于周围(上下左右)4个临格的数值的和,如果大于则该矩阵不能由全零矩阵得到 解法一:可能是我能想到的最复杂的方法 1)将二维数组根据行优先原则,变为一维数组。 2)然后对一维数组进行排序,取不为零的值,将元素对应的值拆分成对应个数该元素,然后全排列。这样得到所有可能的矩阵元素递减策略。例如A[0][0] = 3则对应A[0]拆分成3个A[0]... 阅读全文
posted @ 2012-08-20 17:42 MXi4oyu 阅读(236) 评论(0) 推荐(0)