LintCode 1676: Skip Stones (binary search好题!!!)

  1. Skip Stones
    cat-only-icon
    CAT Only
    中文English
    There are n stones between the starting point and the end point. The distance between the starting point and the ith (i starts from 0) stone is d[i]. And the distance between the starting point and end point is target. From the starting point, we can only jump to the adjacent stone until the end point.

Now you can remove at most m stones. Return the maximum value of the shortest jump distance in your jumping from start point to end point.

Example
Example 1:

Input: n = 5, m = 2, target = 25, d = [2,11,14,17,21]
Output: 4
Explanation: Remove the first stone and the third stone. Then the jump path is :

  1. 0 -> 11 11
  2. 11 -> 17 6
  3. 17 -> 21 4
  4. 21 -> 25 4
    Example 2:

Input: n = 0, m = 0, target = 10, d = []
Output: 10
Explanation: No stones and no need to remove any stone. Just jump from starting point (0) to end point (10).
Notice
0 \leq m \leq n \leq 50,0000≤m≤n≤50,000
1 \leq target \leq 1,000,000,0001≤target≤1,000,000,000
These stones are given in order from small to large distances from the starting point, and no two stones will appear in the same place.

思考:这题正确的解法应该是Binary Search或DP。但输入数据量过大,所以Binary Search是唯一正解。
我开始的思路是用map或自建一个ResultType来存储val(gap)和index之间的关系,但是这是行不通的,因为可能多个index有同一个gap。

解法1:Binary Search。

代码如下:

class Solution {
public:
    /**
     * @param n: The total number of stones.
     * @param m: The total number of stones you can remove.
     * @param target: The distance from the end to the starting point.
     * @param d: The array that the distance from the i rock to the starting point is d[i].
     * @return: Return the maximum value of the shortest jump distance.
     */
    int getDistance(int n, int m, int target, vector<int> &d) {
        if (n == 0) return target;
        int start = 0, end = target;
        d[n] = target;
        while(start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (isValid(n, m, target, d, mid)) start = mid;
            else end = mid;
        }
        if (isValid(n, m , target, d, end)) return end;
        return start;
    }
    
private:
    bool isValid(int n, int m, int target, vector<int> & d, int gap) {
        int count = 0, lastPos = 0;  
        for (int i = 0; i <= n; ++i) {
            if (d[i] - lastPos < gap) count++;
            else lastPos = d[i];
        }
        
        if (count <= m) return true;
        return false;
    }
};

解法2:DP。
TBD。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值