数据结构与算法
zhang_shuai12
料峭春风吹酒醒,谁怕?一蓑烟雨任平生。
展开
-
Longest Palidrome Substring问题
最长回文子串问题是比较经典的问题,在面试中经常会碰到。主要的解决方法包括暴力求解,动态规划,备忘录法等。 对于动态规划状态转移方程为: C++代码实现:#include<iostream>#include<string>using namespace std;string longestpalidsubstring(string s){ const int n = s.size();原创 2015-06-06 17:42:18 · 375 阅读 · 0 评论 -
两个单链表的第一个公共节点
题目:求两个单链表的第一个公共子节点。思路:我们可以先遍历两个单链表得到长度,然后求得两个链表长度的差值,然后让长的那个链表先走到差值长度位置,然后两个链表再同时遍历,直到找到第一个公共节点。struct ListNode { int value; ListNode *next;};int getListLength(ListNode *head){ if(head ==原创 2015-06-14 18:18:08 · 679 阅读 · 0 评论 -
在O(1)时间删除链表结点
题目:题目:给定链表的头指针和一个结点指针,在O(1)时间删除该结点。 思路:通常情况下,如果我们要删除单链表的一个节点,我们需要遍历链表找到这个节点的前一个节点,然后执行删除操作,时间复杂度为O(n). 我们试着换一种思路,事实上,我们可以从给定的结点得到它的下一个结点。这个时候我们实际删除的是它的下一个结点,由于我们已经得到实际删除的结点的前面一个结点,因此完全是可以实现的。当然,在删除之前原创 2015-06-14 18:10:34 · 404 阅读 · 0 评论 -
找出数组中只出现一次的数字
题目:一个数组里除了一个数字之外,其他的数字都出现了两次。请写程序找出这个只出现一次的数字。 例如:A[] = {1,2,2,3,3};输出1.思路:我们联想到异或的性质,若两个数相同,异或结果为0,因此若对数组中的数从头到尾异或一遍,所得的结果就是那个只出现一次的数字。int uniqueNumber(int A[],int length){ int result = A[0];原创 2015-06-13 09:57:27 · 398 阅读 · 0 评论 -
某个数的阶乘尾部含有0的数
题目:计算某个数阶乘尾部所含0的个数。例如:5!=1*2*3*4*5=120尾部含有一个0.思路:我们知道一个数要产生0,该数肯定是2的倍数或是5的倍数。对于对于某个数的阶乘,我们将其做质因数分解,n!=(2^x)(3^y)(5^z)*…….,产生0的个数肯定为min(x,z),而一个数分解为5的倍数的个数肯定大于等于2的倍数的个数。即min(x,z) = z,因此我们只需考虑5的倍数的个数。int原创 2015-06-12 10:03:39 · 349 阅读 · 0 评论 -
数组中出现次数超过一半的数字
题目:数组中出现次数超过一半的数字。思路: 通常做法是先对数组排序,然后再遍历一遍数组即可找到。但是这样做时间复杂度为O(n*logn).在面试中,这样做肯定不行。 我们不妨换一种思路,如果某个数字在数组中出现次数超过数组长度一半,则其余数字出现之和一定小于数组长度一半。 因此我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字,一个是次数。当我们遍历到下一个数字的时候,如果下一个数原创 2015-06-11 14:45:25 · 369 阅读 · 0 评论 -
二叉树的子结构
题目:输入两棵二叉树A和B,判断树B是不是A的子结构。思路:主要分两步:第一步)在树A中找到和B的根结点的值一样的结点;第二步)再判断树A中以该节点为根结点的子树是不是包括和树B一样的结构。这可用递归来解决。struct BinaryTreeNode { //二叉树节点定义 int value; BinaryTreeNode *left; BinaryTreeNode *ri原创 2015-06-11 13:45:54 · 1201 阅读 · 0 评论 -
不用+、-、×、÷对两个数求和
题目:不用+、-、×、÷对两个整数求和。思路: 主要分成3步: 第一步不考虑进位,对每一位相加。0加0与1加1的结果都0,0加1与1加0的结果都是1。我们可以注意到,这和异或的结果是一样的。对异或而言,0和0、1和1异或的结果是0,而0和1、1和0的异或结果是1。 接着考虑第二步进位,对0加0、0加1、1加0而言,都不会产生进位,只有1加1时,会向前产生一个进位。此时我们可以想象成是两个数先做原创 2015-06-11 21:32:06 · 1374 阅读 · 0 评论 -
找出排序数组中和为给定值的两个数字
题目:输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。 例如:A[]={1,2,3,4,5,6,7,8,9}, sum = 15,输出6,9.思路: 因为数组是有序的,因此我们可设两个指针left,right,分别从头和从尾部遍历,若A[left] + A[right]原创 2015-06-11 12:40:27 · 1492 阅读 · 0 评论 -
二叉树的深度
题目:输入一棵二元树的根结点,求该树的深度。思路: 如果一棵树只有一个结点,它的深度为1。如果根结点只有左子树而没有右子树,那么树的深度应该是其左子树的深度加1;同样如果根结点只有右子树而没有左子树,那么树的深度应该是其右子树的深度加1。如果既有右子树又有左子树呢?那该树的深度就是其max(左子树,右子树深度)+1。struct BinaryTreeNode { int value;原创 2015-06-10 22:04:28 · 383 阅读 · 0 评论 -
二叉树两结点的最低公共父结点
题目:求二叉树中任意两个节点的最低公共父节点。思路: 从根结点开始遍历,判断以当前结点为根的树中左右子树是不是包含我们要找的两个结点。如果两个结点都出现在它的左子树中,那最低的共同父结点必出现在它的左子树中;如果两个结点都出现在它的右子树中,那最低的共同父结点也出现在它的右子树中;如果两个结点一个出现在左子树中,一个出现在右子树中,那当前的结点就是最低的共同父结点。struct BinaryTre原创 2015-06-11 21:17:39 · 345 阅读 · 0 评论 -
判断二叉树是否为平衡二叉树
题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。思路:我们知道,若二叉树中任意某结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。这可以用递归实现,在遍历二叉树各节点事,若节点的左右子树的深度之差不超过1,则是平衡二叉树。struct BinaryTreeNode { int value; BinaryTreeNode *left; BinaryTreeNo原创 2015-06-10 23:03:25 · 1525 阅读 · 0 评论 -
Morris Traversal 二叉树遍历算法
我们知道,对于二叉树遍历可以用递归方式和非递归方式,时间复杂度和空间复杂度均为O(n). 但如果要求空间复杂度为O(1),显然这两种方式均不满足。这里我们有一种Morris遍历算法,使得时间复杂度为O(n),空间复杂度为O(1)。要使用O(1)空间进行遍历,最大的难点在于,遍历到子节点的时候怎样重新返回到父节点(假设节点中没有指向父节点的指针),由于不能用栈作为辅助空间。为了解决这个问题,Mo转载 2015-05-25 13:42:37 · 585 阅读 · 0 评论 -
带环单链表的环入口点
判断一个单链表是否带环,我们可以设置两个指针,一快一慢,慢的指针每次走一步,快的指针每次走两步,如果在遍历过程中,快慢指针相遇,则表明链表有环,否则无环;而,如何找到环的入口点呢? 给出一个定理:快慢指针的相遇点到环入口点的距离等于头结点到环入口点的距离;LinkList Node { int value; LinkList next;};LinkList findCircleNo原创 2016-09-10 11:50:26 · 726 阅读 · 0 评论