![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
编程之美
xflame
这个作者很懒,什么都没留下…
展开
-
电话号码对应英语单词
电话号码盘一般可以用于输入字母,如2可以输入A、B、C,等等。要求设计号码所对应的所有组合。如5969872可以对应:JTMWTPA、JTMWTPB等。 这就相当于排列数,如5对应J、K、L,以J、K、L各自引出9对应的W、X、Y、Z这些数字的组合就构成一棵树。 我们可以构建一个二维数组charc[10][10]={“”,“”,“ABC”···}并将各个数字所能代表的字符总数记原创 2013-08-19 16:33:33 · 1010 阅读 · 0 评论 -
数组循环移位
设计一个算法,把一个含有N个元素的数组循环右移K位,要求时间复杂度为O(N),且只允许使用两个附加变量。 K可能大于N,但对K%N就可。代码如下:reverse(int* arr,int b,int e){ for(;b int temp= arr[e]; arr[e] =arr[b]; arr[b] =temp;原创 2013-08-18 16:35:13 · 703 阅读 · 0 评论 -
求数组的子数组之和的最大值
思想二:用分治的思想,如果将所给数组(A[0],…,A[n-1])分为长度相等的两段数组(A[0],…,A[n/2-1])和(A[n/2],…,A[n-1]),分别求出两个数组各自的最大子段和,则原数组最大子段和为以下三种情况的最大值:(1)最大子段和为(A[0],…,A[n/2-1])的最大子段和;(2)最大子段和为(A[n/2],…,A[n-1])的最大子段和;(3)最大子段和跨过其中间两个元原创 2013-08-12 15:01:29 · 620 阅读 · 0 评论 -
子数组之和的最大值(二维)
二维情况下,定义“部分和”PS[i][j]等于以(1,1),(i,1),(1,j),(i,j)为顶点的矩形区域的元素之和。则以(i_min,j_min),(i_min,j_max),(i_max,j_min),(i_max,j_max)为顶点的矩形区域的元素之和,等于PS[i_max][j_max]-PS[i_min-1][j_max]-PS[i_max][j_min-1]+PS[i_min-1]原创 2013-08-12 15:01:54 · 639 阅读 · 0 评论 -
子数组的最大乘积
给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合乘积中最大的一组,并写出算法的时间复杂度。(注意,因为数组中数可正可负,通过排序去除最小的显然不能满足要求,如乘积为负,你去除最小的负值显然不对,应该去除最大的负数值) 解法一:可以通过“空间换时间”策略。从数组两边计算乘积,设array[]为初始数组,s[i]表示数组前i个元素的乘积,s[i]=s[i-原创 2013-08-11 18:45:40 · 602 阅读 · 0 评论 -
快速寻找满足条件的两个数
能否快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的数字? 解法一:穷举,从数组中任取两个数字,计算两者之和是否为给定的数字。时间复杂度为(n*(n-1)=O(n2))。 解法二:对数组中每个数a,都判断sum-a是否在数组中。用排序+折半查找,时间复杂度为O(Nlog2N+N*log2N)=O(Nlog2N)。或用hash表,额外增加O(N)的hash表存储空原创 2013-08-11 18:44:58 · 633 阅读 · 0 评论 -
寻找数组中的最大值和最小值
我能想到的是:扫描一遍,用max和min存储扫描过程中的最大值和最小值,数组中两个数据比较后,拿大的跟max比较,拿小的跟min比较,总的时间复杂度是1.5N。另一种方法可以用分治的思想:在N个数中求最小值min和最大值max,我们只需分别求出前后N/2个数的min和max,然后取较小的min,较大的max即可。分治法的时间复杂度计算可以借鉴下:f(2)=1(两个的话只需要比较一次),f(N)原创 2013-08-10 12:30:39 · 732 阅读 · 0 评论 -
寻找最近点对
一维的数很简单,先排序,再扫描已排好的数,相邻两个进行比较即可,时间复杂度为O(N*log2N+N)= O(N*log2N)。两维的话:把平面上N个点分成两部分left和right。假设分别求出left和right两部分最短距离mindistleft和mindistright,还有一种情况就是点对中一个点来自于left部分,另一个点来自于right部分,设min=min(mindistleft原创 2013-08-10 12:31:12 · 818 阅读 · 0 评论 -
找符合条件的整数
任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0。 第一想法:从小到大枚举M的取值,然后再计算N*M,最后判断它们的乘积是否只含有1和0。该方法时间复杂度太高。 第二想法:因为问题要求N*M的十进制表示形式里只含有1和0,尝试去搜索N*M,需要搜索的空间要小很多。 终极思路:(避免多于的除法验证余数)如1%3=1;1原创 2013-08-09 14:59:06 · 647 阅读 · 0 评论 -
斐波那契数列
对于数列a[n],递推公式为a[n+1]=pa[n]+qa[n-1],其特征方程为x^2=px+q (一个数列:X(n+2)=C1X(n+1)+C2X(n);设r,s使X(n+2)-rX(n+1)=s[X(n+1)-rXn];所以X(n+2)=(s+r)X(n+1)-srXn;C1=s+r并且C2=-sr;消去s就导出特征方程式r^2-C1*r-C2=0),即x^2-px-q=0,(1)若方程有两原创 2013-08-09 14:59:41 · 712 阅读 · 0 评论 -
最大公约数问题
解法一:欧几里得的辗转相除法。f(x,y)=f(y,x%y),f(a,b)表示a,b最大公约数。int gcd(int x,int y){ return (!y)?x:gcd(y,x%y);}解法二:对于大数而言,取模运算(其中用到除法)是非常昂贵的开销。用辗转减法:f(x,y)=f(x-y,y),这边需要注意的是要维持左边的数大于右边的数。解法三:(1)对于y和x来说原创 2013-08-08 13:25:25 · 549 阅读 · 0 评论 -
精确表达浮点数
用分数形式表示小数。有限小数或者无限小数都可以转化为分数。方法:对于有限小数X=0.a1a2a3···an,X=(a1a2a3···an)/10^n。对于无限循环小数X=0.a1a2a3···an(b1b2···bm),X=( a1a2a3···an+0.(b1b2···bm))/10^n。再对付小数部分,Y=0.b1b2···bm(b1b2···bm),则(10^m)*Y= b1b2···b原创 2013-08-08 13:24:36 · 464 阅读 · 0 评论 -
寻找最大的K个数
解法一:先排序,再取出前K个,总时间复杂度O(n*logN)+O(K)= O(n*logN)。 解法二:快排思想。假设N个数存储在数组S中,我们从数组S中随机找出一个元素X,把数组分为两部分Sa和Sb。Sa中的元素大于等于X,Sb中元素小于X。这时,有两种可能性:(1)Sa中元素的个数小于K,Sa中所有的数和Sb中最大的K-|Sa|个元素就是数组S中最大的K个数。(2)Sa中元素的个数原创 2013-08-07 14:05:46 · 726 阅读 · 0 评论 -
寻找发帖“水王”
发帖水王发帖数目超过帖子总数的一半。如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的ID也在里面,要求快速找出这个传说中的水王。方法一:最直接的方法,对所有ID进行排序,然后再扫描一遍排好的序的ID列表,统计各个ID出现的次数。如果某个ID出现的次数超过总数的一半,则输出这个ID。这个算法的时间复杂度为O(N*logN+N)。方法二:如果ID列表已经是有序的,那么ID列表的原创 2013-08-07 14:04:58 · 828 阅读 · 0 评论 -
求二进制数中1的个数
解法一:利用除法,通过相除和判断余数的值来进行分析。解法二:使用位操作。与0x01进行与运算。解法三(精辟):代码如下:int count(int v){ int num = 0; while(v){ v&=(v-1);//通过这种方法,可以使v中最小的1编程0,犀利!我没想到··· num++; }}原创 2013-08-07 14:04:22 · 488 阅读 · 0 评论 -
程序理解和时间分析
这个数i不能被2-31这30个数中的两个相邻的数整除,但能被其它28个数整除。所以,这个i肯定是其它28个数的最小公倍数的整数倍。然而i不能被两个相邻的数整除,所以必然是分解质因子后要么i的质因子中不包括这两个数的质因子,要么是i的质因子的次数小于这两个数中相同质因子的次数。只需要给2-31这30个数分解质因数,找一下是否有这样的相邻的两个数,要么它们的质因子中有其它数没有的质因子,要么对于相同的原创 2013-08-19 16:33:04 · 669 阅读 · 0 评论 -
区间重合判断
给定一个源区间[x,y](y>=x)和N个无序的目标区间[x1,y1][x2,y2][x3,y3]…[xn,yn],判断源区间[x,y]是不是在目标区间内? 方法:对N个无序区间按x进行快排成从小到大的序列(记得y也要对应),时间复杂度为(O(N*log2N)),再对这些区间进行合并,时间复杂度为O(N),最后进行查找(可用二分查找)课判定[x,y]是否被合并后的这些互不相交的原创 2013-08-19 16:32:19 · 658 阅读 · 0 评论 -
数组分割
有一个没有排序、元素个数为2n的正整数数组,要求:如何能把这个数组分割为元素个数为n的两个数组,并使两个子数组的和最接近?(变相的背包问题,01背包问题(非完全背包问题),还是有点出入,这边要求个数是n) 2n个正整数数组好比财宝,数组和的一半表示背包容量,为如何才能使背包尽可能装满,并且财宝个数为n。核心代码如下:定义:isOK[i][v]表示是否可以找到i个数,使得它们之和等原创 2013-08-19 16:31:58 · 613 阅读 · 0 评论 -
求数组中最长递增子序列
例如在序列1,-1,2,-3,4,-5,6,-7中,其最长的递增子序列为1,2,4,6。解法一:假设在目标数组array[]的前i个元素中,最长递增子序列的长度为LIS[i]。那么,LIS[i+1]=max{1,LIS[k]+1},array[i+1]>array[k],forany kLIS[i]是指:假设在数组的前i个元素中,以array[i]为最大元素的最长递增子序列的长度)。思想:原创 2013-08-18 16:34:50 · 742 阅读 · 0 评论