
常用算法
PYB不开心
这个作者很懒,什么都没留下…
展开
-
麻将胡牌判定的判定算法
麻将胡牌判定的判定算法问题背景 :简化了麻将规则,给定[1s-9s],[1b-9b],[1t-9t]一共27种牌,每种牌都有4张。需要判断给定的牌是不是胡牌。胡牌的定义为:14张牌里面由一个对子,四个坎组成。其中对子代表两张一样的牌,坎代表三张一样的牌,或者三张连续的牌(连续指: 1s,2s,3s | 4t,5t,6t) 举例:1s,1s,2t,3t,4原创 2018-01-13 23:39:36 · 7905 阅读 · 2 评论 -
A-priori算法的优化实现
前几天做了一个作业,要求算出0-9999每一个的质因子计算出频繁集。以前的简单程序计算太慢,需要30多秒,仔细思考了一下,发现计算过程有很多的冗余。花了3个小时进行优化,结果改进到0.15s就可以算出来。(1)优化1:(1)优化1:不再区分每一个bucket对应的k频繁集,而是将所有的频繁集放在一个集合里面。(2)优化2:(2)优化2:针对每一个候选频繁集的过滤,我们可以采取如下策略:因为候选频繁集原创 2016-10-08 11:17:25 · 1211 阅读 · 0 评论 -
Maigc Cubes:2017 Works Application笔试
给定一个M*M*M的魔方,和N个小魔方,将每一个小魔方融合到大魔方里(小魔方的大小不确定,但是一定小于大魔方),融合的部位将将加起来再对P取余,要求最后的结果一定是全部为0。求出所有小魔方的位置。思路如下,这个题目似乎没有找到巧妙的解法,所以采用暴力搜索.但是搜索也是有技巧的,我思考之后发现:这个问题很适合双向BFS搜索加减枝。从最终状态全0出发,我们可以每次减去一个魔方的值然后取余(-1%3 =原创 2016-10-31 11:00:11 · 2095 阅读 · 0 评论 -
快速求解一个数位数的和
naive的方法就是一位一位的统计了,但是通过一个为运算的技巧,我们可以快速的求解这个问题。(1)不妨假设这个数不超过64位,利用下面代码for循环里面的计算,可以并行的求解8个字节的位数和。(1)不妨假设这个数不超过64位,利用下面代码for循环里面的计算,可以并行的求解8个字节的位数和。(2)接下来将val分布在8字节的和加起来(2)接下来将val分布在8字节的和加起来 注意这里采用对半相加的办原创 2016-10-17 12:34:29 · 1188 阅读 · 1 评论 -
K-means基于的简单实现
简单实现k-means算法和non standard k-means方法。基本思想就在于找到一组center以后,对新的数据进行聚类,直到误差不再变化。def dis(a,b): return ((a[0]-b[0])**2+(a[1]-b[1])**2)**(0.5)def Error(x,y): assert(len(x)==len(y)) z = (0原创 2016-10-01 09:48:01 · 556 阅读 · 0 评论 -
华为面试题:求n对括号的所有合法表达式(两种简洁做法)
这个题目其实以前写过,但是现在再看,有了简洁有效的多的解法:一个DFS就搞定了。同时可以分析一下n对括号的合法表达式有多少种?F(n)=∑n−1k=0F(k)∗F(n−1−k)F(n) = \sum_{k=0}^{n-1}F(k)*F(n-1-k),具体思路很简单,但是闭式表达式我求不出来。def construct(n): def create(num1,num2,exp):原创 2016-08-08 23:16:51 · 1664 阅读 · 0 评论 -
Python建立简易语音识别系统
将AI课上学习的知识进行简单的整理,可以识别简单的0-9的单个语音。基本方法就是利用库函数提取mfcc,然后计算误差矩阵,再利用动态规划计算累积矩阵。并且限制了匹配路径的范围。具体的技术网上很多,不再细谈。现有缺点就是输入的语音长度都是1s,如果不固定长度则识别效果变差。改进思路是提取有效语音部分。但是该部分尚未完全做好,只写了一个原形函数,尚未完善。 import waveimport num原创 2016-10-24 22:55:51 · 35537 阅读 · 5 评论 -
Leetcode:Substring with Concatenation of All Words
下面提供了两种算法解决这个问题:算法1:算法1:每遇到一个字母就查找它是不是属于首字母集合,若是则开始解析。解析的时候要注意某个单词的数量不能超过此数。一开始利用递归写的的解析函数超时了,改为循环后成功AC。class Solution(object): def findSubstring(self, s, words): def parse(start,d=0):原创 2016-09-26 23:43:04 · 351 阅读 · 0 评论 -
Leetcode:正则表达式.
class Solution(object): def isMatch(self, s, p): print(s,p,'...') i,n = 0,len(p) if s=='':return p=='' or (len(p)>=2 and p[1]=='*' and self.isMatch('',p[2:])) if p==原创 2016-09-25 18:55:30 · 985 阅读 · 0 评论 -
LeetCode:Median of Two Sorted arrays
给定两个有序的数组,求出这两个数组的中位数。这个题目最简单的解法就是直接合并然后求取,复杂度是O(m+n)的复杂度,但是这样是不能通过测试的。下面给出一个二分的思路来解决问题:分析分析:我们首先求取两个数组中第k大的元素,不妨假设从a中取前pa个元素,b中取前pb个元素。pa+pb=k,假如a[pa]>b[pb],那么我们知道两个数组合并后的序列中a[pa]一定位于b[pb]之后,这也说明b中的前p原创 2016-09-25 13:07:19 · 338 阅读 · 0 评论 -
确定任意可重复集合某一排列的字典序
(1)(1)首先考虑某一个不重复集合的排列字典序。这很容易比较,只需找出有多少种排列小于它既可。从第一个元素x开始遍历,不妨假设后面的元素有i个小于x,那么一共有x*(n-1)!种情况。假如没有,则需要保持第一个元素不动,类似的方式判断第二个元素。最后将所有的种类加起来既可(2)(2)假如有重复的元素,那么问题将会变得复杂很多。按照(1)的思路继续,我们假设第一个x后有j个元素小于x,那么我们必须要原创 2016-09-01 12:40:59 · 528 阅读 · 0 评论 -
PageRank算法的简单实现.
PageRank值可以看作是一个特殊矩阵A的特征向量,R = A*R,经过多次迭代R将会收敛。具体的数学分析请看Wiki.下面的代码实现了简单的PageRank算法,从一个图中读取网页节点的关系,然后将这种关系转换成为概率矩阵(也可以说是权重),然后利用快速求幂算法求出AnA^n,最后得到需要的A.中间利用了矩阵的转置等算法.全部用python手写,没有引入numpy.def create(q,gr原创 2016-09-21 08:58:40 · 2256 阅读 · 0 评论 -
算法竞赛入门第七章:竞赛选讲(Uva12325,Uva1603)
宝箱Uva12325:宝箱 Uva12325:这道题很有思维强度,首先比较容易想到的是枚举宝箱的数量,从0到[n/s1]或者0到[n/s2]。但是由于输入很大,当s1,s2都很小的时候,那么枚举的数量将会非常的巨大。因此针对s1,s2较小而n很大的情况,需要提供另一种思路。另一种枚举的思路是从s1,s2入手的。因为s1,s2很小,如果枚举的数量和他们成正相关,那么就可以确保枚举的效率。考虑一个事实:原创 2016-09-06 11:29:32 · 1210 阅读 · 0 评论 -
坐标的旋转,翻转
因为一个旋转的变换是(x,y)->(y,-x),所以只需要三次连续旋转就可以获得所有的旋转。而翻转的类型则是(x,y)->(x,-y),翻转之后再旋转则得到另外的图形。如果给定了相应的坐标范围,则要注意旋转之后会超过坐标范围,因此需要利用平移将图形移回定义的坐标系。注意,这也是一个小技巧,不管一个图形的位置如何,我们都可以将它标准化到坐标系的左上角,这样就消除了平移的影响。下面的代码还加上了去掉重复原创 2016-09-06 23:12:26 · 4480 阅读 · 0 评论 -
算法竞赛入门第七章(1):暴力枚举
例题1例题1:此题比较简单,先写一个10取5的排列函数(可以适用其他的排列),然后进行进行查表。当然如果解约空间就可以直接循环加判定字母是否重复来解。def create(m,obj = list(range(10))): def remove_2(x,L): L = L[::] L.remove(x) return L ans = [原创 2016-08-14 19:20:27 · 596 阅读 · 1 评论 -
最大公约数和快速gcd
最大公约数有两种基本的求法:(1)辗转相除法(2)更相减损法,首先来证明一下:(1)证明gcd(a,b)=gcd(b,a(1)证明gcd(a,b) = gcd(b,a%b)假设a=k1m,b=k2m,a=sb+r假设a = k_1m,b = k_2m,a = sb+r可以知道r=a−sb=(k1−sk2)m,所以m是(b,r)的公约数可以知道r = a-sb = (k_1-sk_2)m,所以m是(b原创 2016-11-01 15:40:16 · 3323 阅读 · 0 评论 -
基于模型融合的推荐系统实现(3):模型融合
基本思路很简单,最小二乘法就好了:我们假设两个算法得到的结果权重分别是a,b利用最小二乘法和我们分出来的第二部分数据就可以获取a,b使得误差最小。其实最小二乘法就是求一个广义的逆即可。最后的RMSE比起单一的模型有所提高,变成了(0.86~~~~)import numpy as npfrom code import read_filefrom SVD import construct_matri原创 2016-11-29 19:19:21 · 2478 阅读 · 3 评论 -
网易笔试的两道dp问题
#include "iostream"#include "vector"#include "algorithm"#include "string"#include "cmath"using namespace std;int main(void){ int n; string k; while (cin >> k) { cin >> n;原创 2017-03-29 18:51:18 · 593 阅读 · 0 评论 -
高效大整数运算库-------An Efficient Library for BigInteger
———-高效的高精度大整数库———-————-本着锻炼一下编程和优化能力的目的,花了两个多星期完成了这个作品。具体的性能比较可以参考这个:性能比较0. 其实在1年多前刚刚开始学习C++的时候也曾经做过一个用字符串来表示大整数的练习,但是运行速度很慢,所以我首先将原来的代码翻了出来看了看,首先把所有的参数改成const &的类型,当时写的时候还不知道引用….所以结果就快了几倍。然后发现了karat原创 2017-03-23 16:53:00 · 2749 阅读 · 3 评论 -
简单五子棋AI
五子棋AI这个项目参考了网上的五子棋源码,并且做出了自己的修改与一定的优化。基本思路:首先我们知道棋类AI的基本框架就是博弈树,使用最大最小搜索算法和alpha/beta剪枝。这是基本的框架。然后因为存在的解太多,所以我们需要考虑一个评估函数来进行选择。[1]评估:这里主要采用状态分析的办法来进行打分。我们首先统计所有的棋形状态(冲二,冲三,活三等等),然后根据双方的状态来打分:具体来说,就是轮到我原创 2017-02-23 18:16:47 · 1455 阅读 · 0 评论 -
k pair of min jaccard distance
一个作业题,计算13万个用户的相似程度,每个用户有两个列表(L,U),分别是喜欢的电影和不喜欢的电影。找到最相似的100对用户。jacard的计算公式:Jaccardij=(Li∩Lj)⋃(Ui∩UJ)(Li∪Lj)⋃(Ui∪UJ)Jaccard_{ij}=\frac{(L_i\cap L_j)\bigcup(U_i\cap U_J)}{(L_i\cup L_j)\bigcup(U_i\cup U_原创 2016-10-09 15:11:41 · 498 阅读 · 0 评论 -
判定一个点是否在三角形内部
给定任意一个点的坐标和一个三角形,判定这个点是否在三角形内部。本文独立思考完成,没有参考别的资料,可能方法不是太简洁。基本思路:[0]:考虑点在三角形内部的特征:任何一条经过该点的直线都一定会和这个三角形有交点,也就是会与某些边有交点。考虑这样的直线的特殊情况使得经过外部的点的直线和三角形没有交点。容易联想到党该直线平行于某一条边的时候,这样的直线一定会与三角形没有交点(可以将三角形外部的平面划分为原创 2017-01-09 15:37:34 · 1408 阅读 · 0 评论 -
三角形填充和分形练习
画出一个六角星,在六角星的两条边上的三等分点作一个新的等边三角形,然后递归的做下去,并且图形的内部必须填充颜色。[0]:首先考虑如何画出一个六角星,基本方法是:先画一个三角形,然后对每一条边的两个三等分点求出第三个顶点,这样以新的三个点作一个三角形和原来的三角形合成在一起就得到了六角星。[1]:接下来考虑如何对每一个小的三角形进行分形:我们以一个三角形的三个顶点作为参数,我们只需要其中的两条边(每条原创 2017-01-09 13:51:54 · 1484 阅读 · 0 评论 -
python实现二十四点
给定n个数字,计算出一个满足24点的表达式:比如1,11,2,1:(11+1)*2/1基本思路就是枚举计算顺序(在一开始进行一次全排列),括号,加减乘除。其实有很多是重复计算过了的。这个程序我为了高效找到一个解就算了,但是我们可以找到所有的解(表达顺序可能会重复,比如1+2和2+1),同时也可以计算多个数字的组合。def compute(x,y,op): if op=='+':return原创 2016-11-26 20:29:06 · 13151 阅读 · 3 评论 -
遗传算法的简单实现(1):求解函数最大值
刚刚了解了一点遗传算法的原理,参照了网上的一篇入门教程自己实现了一下。参数和操作:参数和操作:染色体(表示方法),染色体长度,变异率,交叉率,最大的总群个体数,评估函数,目标函数(在这里与评估函数一致)。对函数对函数搜索最大值。实现思路:将染色体表示为x,y的值(以bit的形式来表示),进行选择,交叉,变异。同时为了保证解具有较好的全局性,我们每次都选择最好的一个解来替代下一代的最差的一个解,同时提原创 2016-12-03 16:21:21 · 12997 阅读 · 2 评论 -
遗传算法的入门实现(2):利用正方形拼接firefox
这段程序没有参考网上的任何代码,属于自己独立完成,因此效果也不是很理想。但是不管怎样,我也花了不少心思研究,就当是述说一下自己的思路吧:(1)(1)首先为什么不用三角形来进行填充呢?因为三角形的绘制和填充本身来说不是一件很容易的事情(对于我来说,虽然我参考了一下网上的算法,已经有了基本的思路,但是还是把精力放在遗传算法上面是重点),而使用正方形则很大的减少了编程的难度。(2)(2)其次在染色体的选取原创 2016-12-04 20:15:39 · 4195 阅读 · 0 评论 -
AdaBoost算法的单机实现
AI课上的作业,我用python实现一下实现的目标如下:首先简单介绍一下Adaboost算法,也叫做自增强适应。用来将多个弱的分类器/预测器变成一个比较强的分类器。具体算法如下:[0]弱分类器我只实现了简单的二分类,然后用AdaBoost算法将这些分类器训练成一个强分类器。[1]强分类器由多个弱分类器加权之后结合而成,每一个弱分类器则有自己的判别规则。这里简单起见只用了最最简单的水平|垂直分类器。[原创 2016-11-20 14:47:19 · 594 阅读 · 0 评论 -
滑动窗口问题
给定一个序列,求出一个字序列ALAR没有重复的值。这个题目看似非常简单,但是却很经典,值得反复捉摸。首先,最简单的办法就是用一个大小为k(k从大到小,发现符合条件的就可以停了)的窗口开始扫描,O(n^2)可以解决。左出右进。但是这个效率还是太低了。其实我们可以对比一下leecode上的最大长方形问题,有没有发现有一点相似呢,我们也是不断拓展右边界(只要可以递增),如果不能拓展了,就“滑动窗口”使得最原创 2016-11-18 22:42:58 · 3866 阅读 · 0 评论 -
数组排列
给定一个整数数组,求该数组的一个排列使得排列之后的数最大:比如[1,3,22,9]=>93221这个问题看似简单,但是要优雅的解决却并不容易.我只找到了dfs的办法进行计算,每次找到首位数最大的一个数字集合,然后枚举其中一个作为当前的位置的元素,然后递归的搜索下去。但是这样的复杂度是很高的。我们来看一下另外一个优雅的解法:定义a>b等价于ab>ba定义a>b等价于ab>ba,然后排序之后的结果即为答原创 2016-11-17 17:32:00 · 2376 阅读 · 0 评论 -
基于模型融合的推荐系统实现(2):迭代式SVD分解
SVD算法的原理网络上也有很多,不再细说了,关键是我们得到的数据是不完整的数据,所以要算SVD就必须做一次矩阵补全。补全的方式有很多,这里推荐使用均值补全的方法(用每一行均值和每一列均值的平均来代替空白处),然后可以计算SVD,作PCA分析,然后就可以得到预测结果。但是我们这里有一个极为关键的思路,迭代是SVD,我们用第一次预测得到的SVD的值来原来的均值预测,然后继续做SVD分解,直到收敛。这里的原创 2016-11-29 19:11:42 · 2002 阅读 · 0 评论 -
基于模型融合的推荐系统实现(1):基于SGD的PMF
(1)PMF算法PMF的基本的思路,就是定义两个基本的参数W,U,然后对于任意一个组合(u,m),利用Wi∗UjW^i*U^j,来获取预测值。这些基本的算法思路网上很多,就不细说了。简单说一下程序[0]:一开始我们要将训练数据划分为3部分,第一部分用来做普通的SGD训练,第二部分用来训练模型融合,第三部分用来测试RMSE。[1]:我们利用SGD(随机梯度下降)来训练函数,最后就可以得到W,U,为了更原创 2016-11-29 19:03:37 · 2116 阅读 · 0 评论 -
A-priori算法的简单实现
A-priori算法是一种先验算法,经常用于数据挖掘里面寻找关联的子集。我们给定一个数据的集合{{1,2,3},{1,2,3,5,4}…{11,19,28}},需要寻找同时出现次数超过s次的k元集合(x1,x2...xk).(x_1,x_2...x_k).其基本核心思路如下:1:首先寻找出现次数超过s次的一元集合,由于这样的集合不会超过元素的总数,一般可以直接计算出来,利用字典(或其他hash结构)原创 2016-09-17 14:48:24 · 2096 阅读 · 0 评论 -
求解最长单调子序列.
给定一个长度N的子序列,求出一个单调递增的最长子序列长度,子序列可以不连续。这道题我暂时只找到了O(N^2)复杂度的算法:可以把问题看作一个简单的DP问题。假设result[k]是代表以第k个元素作为结尾的某一个单调子序列的长度,那么对于第k+1个元素结尾的单调子序列,可以这样计算result[k+1]=max(1+result[i])wherearray[i]<array[k+1],ifrom0t原创 2016-09-17 12:19:23 · 633 阅读 · 0 评论 -
关于视频剪辑算法的简单实现
前段时间看到一个有关视频剪辑的算法,主要用来剪辑那种循环播放的视频片断,关键就是开始和结束画面要非常的相似。思路是将每一帧看作很多象素点构成N维空间的一个点,然后寻找距离小于某一个阀值两个点。由于这种视频不能太长,所以只需要在某一帧的前面k帧寻找就可以,而不需要和其他所有对比。直接编程比较很简单,但是耗时很大,因为一个1024*1024的画面就有10^6个像素点,如果是剪辑一个1小时的视频,那么一共原创 2016-08-14 11:14:47 · 2960 阅读 · 0 评论 -
算法竞赛入门经典(1,2章的python实现)
可以说几乎没有什么难题,但是有几个地方还是值得注意.关乎一些编程的技巧.首先对于最大最小值,注意最好还是用第一个数组里的值作为初始值,避免了人为的假设最大值和最小值.对于浮点数的运算,一定要注意误差,比如转换成整数的时候要采用四舍五入的办法比如调用round函数或者int(f+0.5)。要求四舍五入的时候注意要多求一位.用好双端队列.def average(a,b,c): print('%.原创 2016-04-26 20:22:48 · 1805 阅读 · 0 评论 -
如何创建一个随机数组(元素是1到N-1,不重复)
摘要###(1)创建一个随机数组A[N],其元素分布为1到N-1,且不能重复. (2)有几种算法: {1}用一个附加数组used[N],每生生成一个A[i],令used[i] = 1;在余下的计算中,每次都测试 if used[i] == 1,以避免重复. {2}直接生成1-N-1,然后随机交换A[i],A[k],k通过i随机生成。 (3)分析算法:对原创 2015-08-30 20:37:29 · 1704 阅读 · 0 评论 -
标题:快速排序
摘要:(1)快速排序同样是以O(NlogN)为平均时间界的一种排序算法.当然它的最坏时间界会是O(N^2),当然它是在实践中最快的方法;(2)基本思路是:首先选定一个中间值然后对序列进行处理,使得最后的结果是选定的中间值左边的元素都小于等于它,右边的元素都大于等于它;(3)重点在于如何选择中间值,以及如何使得中间值到达合适的位置.{1}选择中间值:直观上讲,我们需要将序列分成基本相当的两个子序原创 2015-09-03 14:22:48 · 564 阅读 · 0 评论 -
快速选择算法
摘要:选择第k小的元素,用快速排序的思想可以以平均O(NlogN)的时间界做到. (1)首先找到中间值,并且进行排序。 (2)如果左边的子序列的长度|S1|==k-1,那么很显然中间值就是所求. (3)如果左边的子序列的长度|S1| >=k,那么显然这个所求元素就在子序列S1里面,递归的在S1里面求解; (4)如果|S1| < k-1那么k就在S2中. (5)如果遇到一个小的子序列(原创 2015-09-03 14:24:07 · 316 阅读 · 0 评论 -
回溯(穷举)计算碰撞概率
摘要:有5个模块在30s内发送信号,发送需要3s时间。假设每个模块都在整数秒开始发送,求发送不碰撞的概率. 基本思路:穷举所有发送不碰撞的可能组合,然后除以所有发送组合.#define Seconds 30#define Modules 5int solve(int T,int modules){ int sum = 0; if(modules == 0)原创 2015-08-31 17:58:31 · 1207 阅读 · 0 评论 -
打印问题
摘要:(1)假设每次只打印一个数字,利用递归将一个正整数打印出来; (2)假设打印一个实数,并精确到小数点后面第n位,利用(1)打印出正整数部分,然后将小数转换为整数并用(1)打印出来。void printOut(int n) { /该整数的中间数都以正数打出/ if(abs(n) >= 10) { printOut(n/10);原创 2015-08-30 16:20:32 · 350 阅读 · 0 评论