three-sum问题总结
问题概述:
- 有n个鸡蛋和k层楼,且存在一个楼层T,在这个楼层或高于这个楼层时鸡蛋会摔碎,低于这个楼层时鸡蛋完好。
- 在1楼鸡蛋也有可能摔碎,在第k层楼鸡蛋也有可能完好。
- 目标:找到这个楼层T。
解法1
消耗1个鸡蛋,T次投掷。
解决策略:
从1层开始逐层向上进行尝试,直到到达第T层,鸡蛋摔碎。
解法2
消耗lgn个鸡蛋,lgn次投掷。
解决策略:
与二分法解决策略类似,先从中间的楼层开始投掷鸡蛋,如果鸡蛋摔碎,则将区间缩小到第一次投掷楼层下方的区域,否则缩小至上方区域。根据此规则进行递归,直到范围缩小到一层楼。由于使用的是二分法,所以投掷次数与二分法时间复杂度相同,为lgn。且由于用的是二分法的策略且每一次投掷都有可能摔碎鸡蛋,所以消耗鸡蛋个数也为lgn。
解法3
Throw the egg according to the following floor orders {1, 2, 4, 8, …, 2(k-1), 2k}, when the egg breaks, it will limit T to the range of (2(k-1), 2k]. At this time, it costs 1 egg and lgT tosses. Then use the strategy of Biosearch within the range of (2(k-1), 2k], each time increases 1 flooe, at this time it will cost another 1 egg and lgT tosses. In all, it costs 2 eggs and 2 lgT tosses.
解法4
Throw the egg according to the following floor orders {1, sqrt(n), 2sqrt(n), …, (k-1)sqrt(n), ksqrt(n)}. At this time, it costs 1 egg and sqrt(n) toses. If the egg breaks at ksqrt(n) floor, throw the egg from (k-1)sqrt(n) floor to k sqrt(n) floor until the egg breaks, it will cost another 1 egg and sqrt(n) tosses. The total cost is 2 eggs and 2sqrt(n) tosses.
解法5
解法6–最优解
参见:https://blog.csdn.net/joylnwang/article/details/6769160
对于这篇博客,有一个我难以理解的片段:
发现这些关系之后,我们似乎找到解决n个鸡蛋测试m次最大能够解决楼层数的方法。对于D(n,m){n < m}而言,对于其能够测试的最大楼层数k,我们可以构造这样的场景,将第一颗鸡蛋仍在楼层i,使得第i + 1层到第k层是D(n,m-1)可以解决的最大楼层数,第1层到第i - 1层是D(n-1,m-1)可以解决的最大楼层数,由此得到递推关系D(n,m) = D(n -1,m-1) + 1 + D(n,m-1),然后对D(n,m-1),D(n-1,m-1)再按照上述公式分解,直到得出刚才所列的三种可计算情况(n = 1,或者m <= n)为止,再进行回溯累加,就可以得到D(n,m)的值。
对于这个递归关系的得出,我的理解是:
- 假设在第i层扔下鸡蛋,若鸡蛋碎了,则说明范围在(1,i-1),这时鸡蛋还剩n-1个鸡蛋(因为一个已经碎了),对应的尝试次数还剩m-1。所以,这种情况下对应的楼层范围为D(n-1, m-1)
- 若鸡蛋没碎,则说明范围在(i+1, k),这时鸡蛋还剩n个(因为第一个没碎),对应的尝试次数还剩m-1。所以对应的楼层范围为D(n, m-1)
- 再加上第i层,所以+1