
算法题
sdoyuxuan
高产似母猪 一月20篇~ ~
展开
-
最大回文前缀
题目 求一个字符串的最大回文前缀长度。回文是指正反方向读起来都一样的字符串,比如“abcdcba”就是一个回文。 那么abccba的长度为6。列子2:10010的回文长度为4。解析这个题目是求回文前缀的长度,因为是前缀所以意思就是从第一个字符开始如果有回文的话,这个回文长度为多少。 那么有俩种算法都是O(n2) 第一种从头遍历,第二种从尾遍历。 差别在于第二种最优为O(N) 我是这样想的原创 2017-08-28 21:42:13 · 1570 阅读 · 0 评论 -
滑动窗口的最大值
题目描述给一个滑动窗口的大小为W,先给你一个数组大小为N。现在滑动窗口一直滑动一直到末尾,求其次向右滑动时的最大值。分析常规思路每次遍历一遍当前窗口,保存其中最大值。然后继续把窗口向右移动,最终做出答案。时间复杂度 O(N*W)。优化用一个双端队列,用它保存过程中的最大值不再每次遍历窗口。 具体这样的: 当队列为空 1.数组的下标 i尾插进去 。 当队列不为空 1.队尾元素对应的数大于下标原创 2017-10-27 11:20:08 · 240 阅读 · 0 评论 -
求当前数组中,最大值减最小值等于sum的数组个数
分析 应用双端队列,构造一个可以动态的求出当前数组最大值的容器,qmax。同上在构造一个qmin。 从left,right等于开始,如果当前区间的qmax-qmin符合条件,right向右扩充,当不符合条件时,计算上一步符合条件的所有子数组个数。个数公式为 left-right。 计算公式是因为当前数组符合条件,那么当前问题的所有子数组肯定也符合条件。因为当前数组当减少一个元素,子数组原创 2017-10-27 15:07:50 · 428 阅读 · 0 评论 -
LeetCode - Longest Palindromic Substring
题目描述给你一个字符串,找最大回文子串。 ababa , 答案就是 ababa abcbc , 答案就是 cbc 回文字符串就是从头读到尾和从尾读到头都是一样的。分析 我是这样子处理的,把字符串中,从前往后的顺序,定义一个下标pos ,pos从0到size-1。 pos为该子串的头部。然后从后往前面逆序遍历,如果那个字符跟pos处的子串相等,那么开始进入一个函数判断这个字符串是不是回原创 2017-10-29 12:26:56 · 230 阅读 · 0 评论 -
LeetCode - Coin Change
题目描述给你一类货币,货币的张数可以是任意的,然后给你一个aim 目标值,让你找出能兑换出 aim 钱数的最少货币的数量。 coins = [1, 2, 5], amount = 11 return 3 (11 = 5 + 5 + 1)题目分析我们先可以按照题目画出一个表,这个表纵轴代表 0 ~ N-1 每种相应的货币,横轴代表从0~aim的钱数。 现在如图,我们可以分析,dp[i][原创 2017-11-07 11:59:39 · 429 阅读 · 0 评论 -
100亿个query,1G内存如何找出这俩个文件的交集?分别给出近似算法和精确算法?
分析 近似算法,用布隆过滤器,对query进行哈希,开70亿个位,刚好差不多比1G小点,再从第一个文件中,读取query,一 个 一 个映射到布隆过滤器里面,再从第二个文件中读取query,一个一个在布隆过滤器里面查询,看是否存在,因为存在不一定准确,但是不存在一定准确,所以这个是可以解决的,所以它是近似算法。 精确算法,一个query字符串大概算60字节,100亿大概600G,那么我们可以原创 2017-11-05 10:39:02 · 1092 阅读 · 1 评论 -
快速幂logn的算法
思路 我们思考下,一个无符号整数42亿 , 给它去对数 , 结果是不是32 . 那么我们可以看出来本身一个数字的二进制表示其实就是对这个数字取log2n, 这个log2n其实这是这个二进制数字的位数. 在思考下, 4 取以2为底的对数,答案是2,4的二进制位有2位,8同理三位. 那么,我们求p的m次方,是不是可以转换为求m的那些二进制为1,取这些二进制位为1的值的p次方,最终把所有二原创 2017-10-31 10:12:38 · 737 阅读 · 0 评论 -
汉诺塔问题
该问题描述大致上这种题,都是有3座塔。Left , mid ,right 这三个塔。假设Left塔有n个盘子,盘子是从1到n的,1放在2上面,2放在3上面,依次类推,小盘子不能放到大盘子下面,现在我们需要把所有的Left塔的盘子移动到最右边,现在求最优的移动轨迹分析如果,我们要把n个盘子移动到right,需要做三步。 1.我们需要先把 1~i-1的盘子先移动到mid 2.把第i个盘子从Left移原创 2017-10-23 14:01:28 · 586 阅读 · 0 评论 -
LeetCode - ChangeCoins2
题目描述给你一个数组,里面是货币的种类。给你一个aim , 求这个aim有多少种换出的方式解法 //递归 N! int _coin(vector<int> &changes , size_t index ,int aim) { int ret=0; if(index==changes.size()) { r原创 2017-11-10 12:52:25 · 244 阅读 · 0 评论 -
Longest Increasing Subsequence
题目描述找最大递增子序列,dp 时间复杂度 N2, 还可以优化到 NlogN, 不用dp的话非递归十分难解,时间复杂度 N的N次方。 void GetDp(vector<int>&dp,vector<int>&v){ dp[0] = 1; int size = v.size(); int max ; for (int i = 1; i < size; ++i原创 2017-11-10 15:22:28 · 187 阅读 · 0 评论 -
构造Maxtree
题目描述先给你一个数组,每个元素都不重复出现,让你构造一课二叉树,这个二叉树满足,父节点值比子节点值大。要求时间复杂度O(N) 空间复杂度 O(N)分析 它虽然很像堆,但堆的时间复杂度构造的是nlog2n,所以不行。 我们方法是这样的,遍历这个数组,找到每一个数左边第一个最大的和右边第一个最大的,选择它们俩个中较小的那个数。如果左边或右边没有,那么就选择有的那个,如果都没有则这个数肯定是最大原创 2017-10-25 11:51:06 · 322 阅读 · 0 评论 -
LeetCode - ZigZag Conversion
题目描述.The string “PAYPALISHIRING” is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) And then read line原创 2017-11-02 13:54:45 · 236 阅读 · 0 评论 -
Leetcode - Minimum Path Sum
题目描述给你一个MXN的矩阵,返回从0,0到最右下角,最短的路径和。思路dp[i][j] 的位置表示 从开始0,0位置到 dp[i],[j]的最小路径和,它是由当前位置的 matrix[i][j] + std::min(dp[i-1][j],dp[i],[j-1])构成,因为当前点的最小路径和,等于从上来到该位置与从最来到该位置中的最小路径和加上当前位置的值。空间O(mXn)时间O(mXn)原创 2017-11-04 11:23:57 · 186 阅读 · 0 评论 -
最长公共子序列
题目描述给你俩个字符串,找公共最长的子序列串。分析根据第一个串的长度M,第二个串的长度N,建立一个MXN的二维表。 这个表 dp [i][j] ,代表 第一个串从 0 ~ i号下标和第二个串从0~j号下标这俩个字串的最长公共子序列。 那么这个表的初始状态是,dp[0][0]~dp[M-1][0]的值为,如果第一个串的 i 号元素跟第二个串的0号元素相等则值为1否则值为0,但是如果dp[i-1][原创 2017-11-14 12:27:46 · 225 阅读 · 0 评论 -
LeetCode-Split Linked List in Parts
题目描述给你一个链表,给你一个K,让你把链表均分为K份,如果不能均分,则前面的链表应该长于后面的链表思路这个很像分苹果,我们现在把所有节点比喻成苹果。 假设现在有7个苹果,k=3,即篮子为3个。 那么我们分的方案是 3 2 2 这个方案是这样来的 苹果数 / 篮子数 是每一个篮子的苹果的基数,然后如果苹果数%篮子数>0,代表还有一部分苹果是余出来的,则前面的篮子每一个篮子分一个余出来原创 2017-11-19 23:52:30 · 236 阅读 · 0 评论 -
字符串正则匹配
题目描述* 匹配1个或多个 ?匹配一个 abc a*b false abc a?c true a* abc true解法重点就是处理掉*,如果匹配的时候 * 后面没有字符了那返回真,如果有的话,那么很简单, 从str中从后往前拿pattern 中 从*开始到pattern末尾个字符个数的字符,继续递归匹配就搞定了。 如 a*b abc 拿(b,c) 递归 如 a*b原创 2017-11-29 21:38:16 · 454 阅读 · 0 评论 -
斐波那契数列 logn
分析 我们都知道常规解法这个数列存在这个等式 , F(n) = F(n-1) + F(n-2) , 我们通过递归的时间复杂度是 2的n 次方,通过迭代时间复杂度是 O(n)。 可是这个菲薄那切数列里面还有一个数学规律,应用这个规律我们可以把时间复杂度降到 logn 。做法 F(n) = F(n-1) + F(n-2) 可以看出这个是一个递推数列,通过这个递推数列,我们必定可以用矩阵把这个递原创 2017-10-31 14:29:26 · 1325 阅读 · 0 评论 -
LeetCode - 链表平分
题目描述给你一个链表,给你一个K,让你把链表均分为K份,如果不能均分,则前面的链表应该长于后面的链表思路这个很像分苹果,我们现在把所有节点比喻成苹果。 假设现在有7个苹果,k=3,即篮子为3个。 那么我们分的方案是 3 2 2 这个方案是这样来的 苹果数 / 篮子数 是每一个篮子的苹果的基数,然后如果苹果数%篮子数>0,代表还有一部分苹果是余出来的,则前面的篮子每一个篮子分一个余出来原创 2017-12-03 13:40:53 · 245 阅读 · 0 评论 -
斐波那契数列变形之青蛙跳台阶
题目描述一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法?分析这个题目从一个青蛙可以跳上1级台阶,也可以跳上2级台阶这句话就可以看出一个青蛙要最终达到n的台阶,必定是从n-2级的台阶一次跳2级或者从n-1级的台阶一次跳一级跳上来。所以到达n级的台阶方法数等于n-2级与n-1级的方法数之和。代码 int jumpFloor(int number) {原创 2017-10-07 13:58:37 · 511 阅读 · 0 评论 -
Top k - 海量数据处理问题
所谓的top k 问题,海量数据找最大的或者最小的前K个数据。最大的这种问题处理方式:先进行哈希分割,再将这些数据前K个元素建立一个最小堆,如果之后的元素比堆顶大的话,将堆顶元素替换为该元素,这样将剩余的元素依次这样遍历完,这个堆的所有元素就是最大的前K个元素。最小的这种问题处理方式:先进行哈希分割,将这些数据,前K个元素建立一个最大堆,如果其后元素,比堆顶小,用该元素完成替换即可原创 2017-06-15 23:09:25 · 318 阅读 · 0 评论 -
算法应用题之今日头条的还该出多少道题?
题目描述头条的2017校招开始了!为了这次校招,我们组织了一个规模宏大的出题团队。每个出题人都出了一些有趣的题目,而我们现在想把这些题目组合成若干场考试出来。在选题之前,我们对题目进行了盲审,并定出了每道题的难度系数。一场考试包含3道开放性题目,假设他们的难度从小到大分别为a, b, c,我们希望这3道题能满足下列条件: a<= b<= c b - a<= 10 c - b<= 10所有出题原创 2017-08-27 01:23:09 · 998 阅读 · 0 评论 -
从俩个有序数组中找出第K小的数。要求时间复杂度O(logmin(m,n))
思路 该题目要求时间复杂度为O(log(min{m,n})) 所以不能直接遍历任意一个数组这样时间复杂度就不符合了。也不能对任意一数组进行二分查找,因为要求是俩个数组元素合并后的第K小的数,所以直接遍历用二分遍历任意一个数组也是行不通的。 故我们可以以区间的方式解决这个问题。我们先假设第一个数组个数小于等于第二个数组个数。如果不是则交换俩个数组即可。这样的话,先定义俩个区间,第一个区间rang原创 2017-08-25 21:23:57 · 3481 阅读 · 0 评论 -
atoi实现
对于关键字_Bool我们都知道在c中c89是没有bool类型的,c99引用了一个_Bool关键字代表布尔类型。其中当给该关键字赋值非0时,该关键字值为1,给该关键字赋值为0时,该关键字值为0。这也符合c语言之前对于逻辑判断的特性,对于0为假,非0值代表真。bool宏在c99后引用了_Bool关键字后,在stdbool.h头文件中定义了三个宏代表bool类型,第一个宏bool,第二个宏True,第三个原创 2017-08-20 20:40:07 · 297 阅读 · 0 评论 -
给两个文件,分别有100亿个URL,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法。
思路分析1G内存为10亿字节,所以无法把100亿直接载入内存,所以我们可以通过哈希与位图的结合来处理该问题。先哈希到位图上,在把俩个位图按位与求其交集。解法1.我们可以申请100个vector空间,每一个vector空间保存初始化过的1亿个无符号整数。 2.用字符串哈希函数对每个url的MD5结果进行哈希,然后把字符串哈希函数得到的整数结果再进行二次哈希,每个整数都模上100,把该结果作为vect原创 2017-08-18 18:30:30 · 7205 阅读 · 0 评论 -
删除小写字母字符串中重复字符。如果可以,优先删除重复字符中排在比他小字符前面的字符。
将N个字符的数组,循环右移K位。时间复杂度O(N)。思路1申请一块空间大小为之前的2倍,然后左旋K位就代表,新字符串的新起始下标为之前的begin加偏移量k,把新字符串返回即可。这个时间复杂度为O(N)思路2保存0号字符的值,从后往前赋值即可,循环k次。这个时间复杂度为O(KN) 思路1代码#include<iostream>#include<vector>#include<iterator>原创 2017-08-18 17:05:23 · 512 阅读 · 0 评论 -
对数组排序时间复杂度要求O(n)与找中位数不能用排序
对数组排序时间复杂度要求O(n)思路 首先我们常规的排序都不能使用。所以我先遍历了一边数组,找到最小值和最大值。然后以它们的差值动态开辟了一段区间作为闭散列。然后再遍历了一边数组把相应元素的出现次数映射到了闭散列中。最后遍历一边闭散列表,把大于0的元素按其下标和保存的次数,重新赋值给原数组,得此完成排序。代码void sort(int *arr, size_t length){ int原创 2017-08-06 17:32:42 · 3384 阅读 · 3 评论 -
前序和中序序列重建二叉树
思路根据前序和中序的特性,前序序列的一个元素就是树的根元素,那么在中序序列找到相应的元素。找到后该元素前面所有元素都是左子树元素,后面元素都是右子树元素。那么此时跟节点的pleft就是左子树返回的结果,pright就是右子树返回的结果,使之递归即可,递归出口就是前序区间只有一个元素时。 Node* _rebuilt_In_pre_order(int *prestart, int*preEnd, i原创 2017-07-31 18:27:21 · 392 阅读 · 0 评论 -
c语言实现继承和多态
思路成员函数首先c++中的成员函数不过只是存放在代码段,并且第一个参数为与this指针同一个类型的函数罢了。所以如果我们要实现多态首先得有成员函数,那么成员函数虽然我们无法写在代码段,但是我们可以自己定一个函数指针放在结构体内部,用来充当成员函数。继承所谓继承也不过是派生类继承了基类的成员罢了,那么我们既要继承基类的函数指针也要继承基类的成员变量,那么我们可以在表示派生类的结构体中定义一个表基类的结原创 2017-07-31 18:50:12 · 389 阅读 · 0 评论 -
求二叉树中两个节点的最近公共祖先
祖先节点祖先节点指从根开始到该节点路径上的所有节点思路拿到这道题先分析树是什么树,是搜索树还是普通的二叉树。搜索树由搜索树性质可得,如果根的左子树所有节点比根小,根的右子树所有节点比根大。 那么分一下几种情况: 1 某一个节点为根节点,那么公共节点就是根节点了。 2 这俩个节点在不同子树,那么公共节点就是根节点。 3 这俩个节点在同一子树。 所以根据以上分析,可得我们可以通过不断的递归直到原创 2017-07-27 19:21:20 · 1379 阅读 · 0 评论 -
俩链表的差集
题目描述已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。例如,若集合A={5,10,20,15,25,30},集合B={5,15,35,25},完成计算后A={10,20,30}思路首先,我接住了俩段空间,第一个动态数组中存放的是第一个链表中的节点信息和每个节点对应的值信息,第二个动态数组存放的是第二个链表中的节原创 2017-07-27 16:10:56 · 1083 阅读 · 0 评论 -
链表翻转
题目:链表翻转。给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现Node* RotateList(Node* list, size_t k). 思路:这道题我的解决方式是分俩步解决它。 第一步先把链表划为多个小链表,每个小链表长度为K。先把每个小链表完成逆置。原创 2017-07-24 12:53:59 · 251 阅读 · 0 评论 -
给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=3 628 800,N!的末尾有两个0。
思路 这个题拿到我第一个思路是先求出阶乘的结果,然后查看该结果最后一位是否为0,具体就是先%10查看最后一位是否为0,如果是再除以10,消掉最后一位。然后循环一直至最后一位不是0,再把计数器的值返回回去。但是我立马就想到了可能溢出,所以百度了下大概13的阶乘是60多亿,而一个正整数就21亿多。所以这个方法不行。 真正可行的解法是: 因为阶乘是1*2*3*…(n-1)*n ,因为题目要原创 2017-07-21 18:42:39 · 1753 阅读 · 0 评论 -
查找一个字符串中第一个只出现两次的字符。要求 时o(n) 空o(1)
思路 既然空间复杂度要求O(1),那么我们只能建立常数倍的空间。所以又因为是字符,所以可以使用一个大小为256的数组。用它来当哈希表。所以我的解法中申请了一个pair的键值对的数组。first保存的是出现的次数,second保存的是出现的该字符第一次出现在字符串中的下标。所以我们可以遍历一边字符串,我们就可以得到所以字符出现的次数和该字符第一次出现的下标。再遍历一次数组,定义一个min变量,原创 2017-07-19 22:39:00 · 822 阅读 · 0 评论 -
空格替换
原理先oldstr指针遍历一边,记录oldlength与空格个数,然后根据newlength=oldlenth+2*space算出新字符串长度,如果出现新字符串的有效个数大于等于数组大小就返回。然后如果满足小于的话,数组可以处理,那么就从后往前依次遍历处理空格就行。要注意的点一个是传参的时候,谨防传一个NULL指针和传一个空串。空指针一访问就崩溃了,空串的话在我写的函数内不能处理,oldstr一减减原创 2017-07-18 17:38:52 · 213 阅读 · 0 评论 -
栈、队列面试题总结
俩个栈实现一个队列原理图注意一定要谨防pop时,容器内没有元素而引发的错误。class Solution{public: void push(int node) { stack1.push(node); } int pop() { if (stack1.empty()) { cout << "队列中无元素pop失败"原创 2017-07-18 17:30:54 · 511 阅读 · 0 评论 -
如何只在栈上创建对象和只在堆上创建对象与创建出无法继承的对象
对象的几种初始化方式A a; —> 代表调用默认构造函数初始化A a(实参); —>代表调用显示构造函数初始化A a(A()/A(实参)/A的一个对象) —>括号内的第一种和第二种代表先调用构造函数创建临时的对象然后再调拷贝构造函数初始化,第三种方式代表调用拷贝构造函数初始化A a = A的一个对象 —> 调用拷贝构造初始化A a = A::Fun —> A Fu原创 2017-07-17 22:07:26 · 322 阅读 · 0 评论 -
实现一个Add函数,让两个数相加,但是不能使用+、-、*、/等四则运算符。ps:也不能用++、--等等
int Add_Core(int a,int b) { if(b==0) return a; int sum=a^b; int carry=(a&b)<<1; return Add_Core(sum,carry); }原创 2017-07-15 19:35:00 · 793 阅读 · 0 评论 -
求最大子矩阵的大小
题目描述给你一个矩阵,这个矩阵的值不是0就是1,现在让你求出由1构成的矩阵,最大面积是多少?分析 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1如上就是这个图,这个答案是9。但是怎么用函数求出呢? 思路是这样的我们,原创 2017-10-26 13:31:06 · 504 阅读 · 0 评论