群讨论算法积累

来源:互联网 发布:淘宝怎么删除差评手机 编辑:程序博客网 时间:2024/04/30 04:47

1. 如果两个字符串的字符一样,但是顺序不一样,被认为是兄弟字符串,问如何在迅速匹配兄弟字符串。
1)一个字符对应一个素数,相乘然后除(判断相等),然后看结果
2)排序之后,比较是否相等,效率低
3) int alpha[127]

       遍历第一个数组,alpha[array1[i]]++
       遍历第二个数组,alpha[array2[i]]--
       最后如果alpha所有元素都为0,那说明是兄弟字符串了

2.一个整数数组  要达到负数在前  正数在后面 而且还是稳定的   ON时间复杂度   O1空间复杂度  
如:-3,1,2-1-3,4。其实就是把正数后面的第一个负数(如-1)插到第一个正数(1)的前面,负数之间的每个正数(1,2)后移一位,就这么简单。时间复杂度刚好为O(n),控件复杂度为O(1)。

这个解法有问题,复杂度不是o(n)。。。
如果改成链表存储数组,块数据移动只要改变几个指针就好,复杂度为o(1),所以整体可以使复杂度变为 O(n)...但是题目说的是数组,尴尬。


3.找寻二叉树中两个节点的公共父节点中最近的那个节点
简单方法可以解决。
下边是另一个方法,需要学习...有待研究,想记在这里。
RMQ 

 首先利用dfs遍历图的所有顶点并且每条边会遍历两次,这样遍历的顶点总共2*n-1个,依次将遍历的边存在数组e[i]中,并且记录每个顶点的深度,
存入数组level[i]中,我们再开一个数组存每一个顶点首次出现的下标,记录在idx中,这样任意给出两个顶点,我们求出他们对应的下标x,y,然后根据level数组在区间[x,y]中找出深度最小的下标r,这个下标对应的e就是我们要求的节点。这个题目就是将LCA转化为在某段区间中找高度最小的那个顶点。
http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor

4.砝码问题汇总

http://hi.baidu.com/macchinetta/blog/item/b2294bfc98015b8db901a052.html

5.最长区间覆盖长度

题目描述:请编写程序,找出下面“输入数据及格式”中所描述的输入数据文件中最大重叠区间的大小。
1.对一个正整数n,如果n在数据文件中某行的两个正整数(假设为A和B)之间,即A<=n<=B或A>=n>=B,则n属于该行;如果n同时属于行i和j,则i和j有重叠区间;重叠区间的大小是同时属于行i和j的整数个数。
 例如,行(10 20)和(12 25)的重叠区间为[12 20],其大小为9;行(20 10)和(12 18)的重叠区间为[10 12],其大小为3;行(20 10)和(20 30)的重叠区间大小为1。

输入数据:程序读入已被命名为input.txt的输入数据文本文件,该文件的行数在1到1,000,000之间,每行有用一个空格分隔的2个正整数,这2个正整数的大小次序随机,每个数都在1和2^32-1之间。(为便于调试,您可下载测试input.txt文件,实际运行时我们会使用不同内容的输入文件。)

输出数据:在标准输出上打印出输入数据文件中最大重叠区间的大小,如果所有行都没有重叠区间,则输出0。

评分标准:程序输出结果必须正确,内存使用必须不超过256MB,程序的执行时间越快越好。

据说是经典题型,入门必做!!思路刚开始也不知道,网上搜索了下才明白了。

具体如下:将输入的区间按起点从小到大排列,然后对每个区间判断从当前区间起点到目前的end的距离,此距离即为覆盖距离,当覆盖距离大于最大的距离时则更新最大距离。每次循环都要判断是否需要更新end,end表示目前所有区间的最大终点值。

方法1有缺陷,当有包含关系的时候,就会不好使。可以加以改进,当使用end计算重叠长度时,可以根据当前线段的end(i)与end进行比较,哪个小就用哪个计算重叠长度。


2.就是按照左端点排序,然后去掉包含关系的线段,去掉的时候,也要更新最大重叠长度值。去掉包含关系的线段后,再遍历一遍这个些剩下的线段,只需要考察相邻的两个线段就好


6.Description

最近小李子喜欢上了一个温柔、贤惠、漂亮的女生,但是老李子却认为这位女生和他的儿子门不当户不对。于是小李子准备和他的MM私奔,但是却被老李子提前知道了,他把小李子关在了一间密室里,密室中只有一个密码锁。从外观上可以看的出这个密码锁是由10位的0和1组成的。 
小李子知道当这个密码锁上面的每一位都变成0的时候就可以打开了。但是,他不知道正确打开这个密码锁的方法。经过了许久的尝试,小李子发现每次他只能同时选取密码锁上的不相邻的两个数字,然后同时改变它们的状态(即把0变成1,1变成0)。为了小李子得终身幸福,你能告诉他至少需要几次才能打开密码锁么?
 
Input
T组测试数据,每组数据由10个0或者1的字符组成。

Output
对于每组数据输出一行,代表最少需要的次数,如果小李子无论如何都打不开密码锁,则输出”where is my happiness?”。

Sample Input
5
0010100101
1010011011
1100000000
1010000000
1010000010
Sample Output
2
3
2
1
where is my happiness?


操作只有3种,1)同时翻掉两个1,2)同时翻掉一个1和一个0,3)或者同时把两个0翻成1(这个操作只会增加次数,故尽量不用该操作)。
对于只有奇数个1的情况,无论进行何种操作,最后的1的数量还是奇数,所以最后的结果一定会至少剩下一个1,所以无解。
对于只有偶数个1的情况,由于要求次数最少,可以一直使用第一种操作,必要时使用第二种操作。
如果1的个数n为偶数,且n>2,则最后的序列将变成如下两种形式:..0010...0100.. 或者 ..001100..,如果是第一种形式,则再需要一次则可以成功,第二种则需要两次2号操作才能成功。
所以次数为:n>2时,n/2;n=2时,相邻则为2,不相邻则为1.

7.已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10。
转自:http://blog.csdn.net/ljsspace/article/details/6820753

分析:要保证rand10()在整数1-10的均匀分布,可以构造一个1-10*n的均匀分布的随机整数区间(n为任何正整数)。假设x是这个1-10*n区间上的一个随机整数,那么x%10+1就是均匀分布在1-10区间上的整数。由于(rand7()-1)*7+rand7()可以构造出均匀分布在1-49的随机数(原因见下面的说明),可以将41~49这样的随机数剔除掉,得到的数1-40仍然是均匀分布在1-40的,这是因为每个数都可以看成一个独立事件。

下面说明为什么(rand7()-1)*7+rand7()可以构造出均匀分布在1-49的随机数:
首先rand7()-1得到一个离散整数集合{0,1,2,3,4,5,6},其中每个整数的出现概率都是1/7。那么(rand7()-1)*7得到一个离散整数集合A={0,7,14,21,28,35,42},其中每个整数的出现概率也都是1/7。而rand7()得到的集合B={1,2,3,4,5,6,7}中每个整数出现的概率也是1/7。显然集合A和B中任何两个元素组合可以与1-49之间的一个整数一一对应,也就是说1-49之间的任何一个数,可以唯一确定A和B中两个元素的一种组合方式,反过来也成立。由于A和B中元素可以看成是独立事件,根据独立事件的概率公式P(AB)=P(A)P(B),得到每个组合的概率是1/7*1/7=1/49。因此(rand7()-1)*7+rand7()生成的整数均匀分布在1-49之间,每个数的概率都是1/49。


程序:

int rand10()
{
 int x=0;
 do{
  x=(rand7()-1)*7+rand7();
 }while(x>40);
 return x%10+1;
}

注:由朋友问为什么用while(x>40)而不用while(x>10)呢?原因是如果用while(x>10)则有40/49的概率需要循环while,很有可能死循环了。


8.求一个字符串里最长的不重复字串,输出长度,O(n)时间复杂度 

从头扫描,用一个hash函数记录扫描过的字符机器位置。扫描一个字符时,看是否在hash数组里边,不在的话,继续向下扫描;在的话,根据hash数组的值,更新开始位置指针,然后继续上述过程。

原创粉丝点击