标签:
1. 50个灯,有50个按钮,编号为1,2,3……50.刚开始灯全部是熄的,现在依次按按钮,每次按到按钮i,i的倍数编号的灯就变一下状态,问到最后开了几盏灯。
对于一个数,有n个约数就被操作了n次。n为奇数就为亮,偶数就为熄灯。i=n*m,除非这个数是某个约数的平方,否则约数互不相同且成对出现,故最后亮的灯的编号是 1 4 9 16 25 49
2. 利用两个heap维持中位数
假设这个中位数是m,对于所有 x<m 存在一个(Top1最大)最大堆中(保持<m的元素的最大值),x>m存在一个(top1最小)最小堆中。
来了一个新的元素x,如果 x < m,则插入到最大堆中,如果>=m,则插入到最小堆中,如果两个堆的高度差大于2,则将中位数插入到数量小的哪一个heap中,并从数量多得那个head取出根节点作为中位树,同时调整两个堆。
但是在求TopK大/小的时候,maxheap维持最大数,minheap维持最小数。求TopK大的时候,用的是最小堆,求TopK小的时候,用的是最大堆。比如在求TopK大的时候,维持一个最小堆,意思就是维持当前heap中最小的元素,对于一个新来的数,如果小于根节点,直接舍弃,大于根节点,则删除根节点,并插入这个节点,重新调整堆。
3. 二叉树遍历的非递归实现
前序遍历(根左右)
a. 将根节点r(不为空)进栈,然后出栈,输入值
b. 如果r->rightchild不为空,则将r->rightchild进栈(因为rightchild一般是最后一个出)
c. 如果r->leftchild不为空,对这个节点重复a b c 过程
如果r->leftchild为为空,则从栈中弹出一个节点输出
中序遍历(左根右)
a. 将根节点r(不为空)进栈
b. 如果r->leftchild不为空,则一直找到r-leftchild为空,并将路径上的点进栈
出栈,输入值,对于这个节点,
如果右子树为空,继续出栈,如果右子树不为空,对右子树重复上述过程。
后续遍历(左右根),需要一个额外的vistied[]数组
a. 将根节点进栈
b. 如果r->leftchild不为空,则一直找到r-leftchild为空,并将路径上的点进栈
c. 取出stack顶的节点(不是pop)
如果该节点的右子树为空,则pop
如果该节点右子树不为空,但是已经被访问过,则pop
如果该节点右子树不为空,同时也没有被访问过,则对右子树重复上述操作。
参考:http://blog.csdn.net/hitwhylz/article/details/14223781
4. 1 ~ n 中二进制有多少个1
思路一:对每个1~n中的每个数字,if( x%10 ==1 ) { count++; } x = x / 10
思路二:采用递归,1 - 21345 可能分解成 1 - 1345 和 1346 - 21345,首先求1346 - 21345中1的个数,再递归求1 - 1345中1的个数。
对于前面,考虑,length 是 n 的位数
1. 第一位不为1:则带来的1的个数 pow(10,length - 1)
2. 第一位不为1:带来的1的个数 atoi(strN+1) + 1
其它的情况:1出现在次高位:(length -1)× pow(10,length-2)× first
5. 最大连续乘积子串:给一个浮点数序列,取最大乘积连续子串的值,例如 -2.5,4,0,3,0.5,8,-1,则取出的最大乘积连续子串为3,0.5,8
用DP求解,用Max来表示以a结尾的最大连续子串的乘积值,用Min表示以a结尾的最小的子串的乘积值,那么状态转移方程为:
Max[i] = max{a, Max[i-1]*a, Min[i-1]*a} 因为序列中有负数,所以要考虑 Min[i-1]*a 的情况
Min[i] = min{a, Max[i-1]*a, Min[i-1]*a}
Max[1]=Min[1]=a[1]
此题还有一个变形,给定一个长度为N的整数数组,只用乘法,不用除法,计算任意(N-1)个数的组合中乘积最大的一组,并写出时间复杂度。
s[i] : i 之前的所有数乘积
t[i] : i 之后的所有数乘积,都包括i
max{p[i] = s[i-1] * t[i-1]}
还可以通过分析,进一步减少计算量。假设N个整数的乘积为P,针对P的正负性进行如下分析(其中,AN-1表示N-1个数的组合,PN-1表示N-1个数的组合的乘积)。
1. P为0 : 那么,数组中至少包含有一个0。假设除去一个0之外,其他N-1个数的乘积为Q,根据Q的正负性进行讨论:
Q为0
说明数组中至少有两个0,那么N-1个数的乘积只能为0,返回0;
Q为正数
返回Q,因为如果以0替换此时AN-1中的任一个数,所得到的PN-1为0,必然小于Q;
Q为负数
如果以0替换此时AN-1中的任一个数,所得到的PN-1为0,大于Q,乘积最大值为0。
2. P为负数
根据“负负得正”的乘法性质,自然想到从N个整数中去掉一个负数,使得PN-1为一个正数。而要使这个正数最大,这个被去掉的负数的绝对值必须是数组中最小的。我们只需要扫描一遍数组,把绝对值最小的负数给去掉就可以了。
3. P为正数
如果数组中存在正数值,那么应该去掉最小的正数值,否则去掉绝对值最大的负数值。
标签:
原文地址:http://www.cnblogs.com/lbingkuai/p/4551191.html