[备忘]收集的一些题集(更新中)

前言:以下为本人收集的一些题目与解答,文中的大多题目难度并不会太高,仅是本人觉得比较有趣并且又不需要太多专业知识即可解答,不会太伤脑,仅供大家闲暇时把玩。想要专业算法的网友还请绕道!^_^本中解答较多来自网络,本中也标明了出处,有些解答则仅为本人见解,鉴于水平非常有限,其中有必有诸多疏漏,仅供参考!还望广大网友一起更正与完善!先谢过各位大神!~~

---------------------分割线-------------------------

算法:无序实数列V[N]中大小相邻实数的最大差(线性空间和线性时间)

题: 有无序的实数列V[N],要求求里面大小相邻的实数的差的最大值,关键是要求线性空间和线性时间

题目来自CSDN论坛里的讨论,很多网友给出了他们的意见。

其实这个问题要求线性时间条件下,通常会让我们想到桶排序;接着关键是考虑怎么减少桶排序中对桶中各数的排序即可想到解决方法。我的算法如下:

  1. 主要是先找出最大的数与最小的数,然后构造一个n个桶,桶的下标与数的关系为: index = (v[i]-min)/(max-min/n).
  2. 遍历数列,将数值插入到对应的桶中。每个桶最多保留最小和最大的两个元素,不需要多余的数。
  3. 遍历所有的桶,记录每个桶之间有多少个空桶到数据flags中,并求出最大连续空桶数 maxGap。
  4. 最后遍历flags数组,对于空桶数 >= maxGap -1 的元素,计算从前面的最近的不为空的桶中的大元素与当前桶中的最小元素的差,最终找出最大差。

参考:http://blog.xiping.me/2009/11/%E7%AE%97%E6%B3%95%EF%BC%9A%E6%97%A0%E5%BA%8F%E5%AE%9E%E6%95%B0%E5%88%97vn%E4%B8%AD%E5%A4%A7%E5%B0%8F%E7%9B%B8%E9%82%BB%E5%AE%9E%E6%95%B0%E7%9A%84%E6%9C%80%E5%A4%A7%E5%B7%AE%E7%BA%BF%EF%BC%88.html


两个数组a[N],b[N],其中A[N]的各个元素值已知,现给b[i]赋值,b[i] = a[0]*a[1]*a[2]...*a[N-1]/a[i];

要求:
1.不准用除法运算
2.除了循环计数值,a[N],b[N]外,不准再用其他任何变量(包括局部变量,全局变量等)
3.满足时间复杂度O(n),空间复杂度O(1)。

说白了,你要我求b=a[0]*a*...a[i-1]*a*a[i+1]..*a[N-1]/a ,就是求:a[0]*a[1]*...a[i-1]*a[i+1]..*a[N-1]。只是我把a[i]左边部分标示为left[i],b[i]右边部分标示为right[i],而实际上完全不申请left[i],与right[i]变量,之所以那样标示,无非就是为了说明:除掉当前元素a[i],其他所有元素(a[i]左边部分,和a[i]右边部分)的积。读者你明白了么?

    下面是此TX笔试题的两段参考代码,如下:

//ncicc  
b[0] = 1;  
for (int i = 1; i < N; i++)  
{  
  b[0] *= a[i-1];  
  b[i] = b[0];  
}  
b[0] = 1;  
for (i = N-2; i > 0; i--)  
{  
  b[0] *= a[i+1];  
  b[i] *= b[0];  
}  
b[0] *= a[1]; 

13个球一个天平,现知道只有一个和其它的重量不同,问怎样称才能用三次就找到那个球?

参考:http://blog.csdn.net/v_july_v/article/details/6803368#


链表问题

1. 如何判断单链表是否有环。

2. 求环的入口节点。

3. 判断两链表相交问题:
给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。
为了简化问题,我们假设俩个链表均不带环。
问题扩展:
1.如果链表可能有环列?
2.如果需要求出俩个链表相交的第一个节点列?

解:

1. 设两个指针从头开始,P1一次走一步,P2一次走两步,当有环时,会在环内相遇。

2. 解决这个问题,需要解决两个子问题:

a. 环的节点数?b. 如何求单链表的倒数第K节点?

假设我们知道了环的节点数为N,则环的入口节点即是链表的倒数第N点。

首先,求出环节点数。照1的方法,当相遇后,再接到走,并记录P1走过的步数。这回,再次相遇,P1刚好走一圈。当求出环长为N后,让P1,P2指向头节点,这回两指针一次都只走一步,P2先走N步,于是再次相遇就是环入口节点。

3. 详细代码请看参考:http://blog.csdn.net/v_july_v/article/details/6870251。这里仅给文字描述。

若两链表无环且相交,则H1,H2各自走到链表末节点,肯定会相同,否则不相交。

扩展:若链表有环,首先可用问题1判断两链表是否有环,若某一链表无环,则肯定不会相交!只在两个链表都检测到环的情况下,可能出现相交,而如果相交,则环必将是两链表共有的!基于这点,判断的方法就很多了,比如在判断是否有环时,会在环内有相遇的节点,可各返回各自环内相遇的节点P1,P2,一个不动,另一个走,若在一圈内遇到另一个节点,则表明相交;或者找到各自的环入口,解环成单链表,再用原来方法判断也成。


一道概率题:由均匀分布的U(1,N)产生另一个均匀分布U(1,M)

问题起源于这样一道题:

给定一个函数rand5(),使函数rand7()可以随机等概率的生成1-7的整数。

文[1]利用rand5()函数生成1-25之间的数字,丢弃22-25,然后将其中的1-21映射成1-7:

写法一:

  1. int i;  
  2. do   
  3. {   
  4.     i = 5 * (rand5() - 1) + rand5();  // i is now uniformly random between 1 and 25  
  5. while(i > 21);   
  6. // i is now uniformly random between 1 and 21   
  7. return i % 7 + 1;  // result is now uniformly random between 1 and 7  
写法二:
  1. int rand7()   
  2. {   
  3.     int vals[5][5] = {   
  4.         { 1, 2, 3, 4, 5 },   
  5.         { 6, 7, 1, 2, 3 },   
  6.         { 4, 5, 6, 7, 1 },   
  7.         { 2, 3, 4, 5, 6 },   
  8.         { 7, 0, 0, 0, 0 }   
  9.     };   
  10.    
  11.     int result = 0;   
  12.     while (result == 0)   
  13.     {   
  14.         int i = rand5();   
  15.         int j = rand5();   
  16.         result = vals[i-1][j-1];   
  17.     }   
  18.     return result;   
  19. }  

上述对问题的解答已经足够,下文从另外一个角度再考虑,权当扩展一下思路吧:

本题由RAND(1,N)产生RAND(1,M),由于M大于N,所以麻烦了些,如果M小于N呢?则问题变得很简单:随机产生1到N,然后丢掉大于M的数,则输出1到M就是等概的。根据上面的思路我们可以得到均匀的0,1分布:因为有N>2,所以可以容易得到。那么,由U(0,1)怎么去得到U(1,M)呢?想到了二进制,对于M,设其二进制有K位,则我们利用U(0,1)产生K次,得到一个数 r = a(0) * 2^0 + a(1) * 2^1 + ... + a(k-1) * 2^(k-1),其中a(i)服从U(0,1)。那么r则是 0到(2^k)-1里均匀分布的,很显然(2^k)-1 >= M,因此,问题又转化为了由RAND(1,N)产生RAND(1,M),并且N大于M。因此问题得解。


再扩展一下,由01均匀分布去得到不均匀的01呢?比如让0的概率为P,1为1-P呢?

这就可以利用上述提到的由U(0,1)得到U(1,M)的方法解。假设P=0.8吧,通分取整数,则可认为10次里有8次发生0,2次发生1,于是,我们令M=8,并生成U(1,M),然后令 r=u(1,M) <=2时输出1,其它情况输出0。

参考:

[1]http://www.cnblogs.com/graphics/archive/2010/07/10/1774942.html


华为面试题:一类似于蜂窝的结构的图,进行搜索最短路径(要求5 分钟)

这题我的理解是寻找蜂窝上两个节点之间的最短路径,当然经典的D算法等是可以解决的,不过首先得把无限的蜂窝图(因为是通信网的蜂窝,理论上是无限覆盖的)做个限制,否则D算法将不可能有返回了。

这里我想说的一种算法是贪心法,只描述思路,未经权威测试

根据蜂窝图的特点,每个节点都只有三条出路:横向、与斜着的上、下方向。

根据最短路径的子问题重复特点,即,在一条最短路径中,中间经过的节点到目标的最短路径即已包含在这条最短路径中。在蜂窝结构中,它看起来符合贪心规则:从当前点出发,比较三条可选路径,首先横向坐标(X轴)中,能接近目标点的路径(这里先选Y轴也一样啦),如果有两条路径在X方向上接近目标的距离一样,那么再比较Y轴。就是这么简单。不过要注意两两种特殊情况:源与目标在同一X轴或Y轴上,这时,会发生两条路径等价的情况,任选一条即可。如下图给出了几种情况的示意。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值