LintCode 1636: Aerial Movie (双指针法典型题)

  1. Aerial Movie
    In order to prevent passengers from being too bored during the flight, LQ Airlines decided to play two movies during the flight. Since the movie cannot be played during the take-off and landing of the aircraft, LQ Airlines must ensure that the duration of the two movies to be less than or equal to the flight duration minus 30 minutes, and the total length of the two movies should be as long as possible. Now given t ,the flight duration(minutes), and array dur[],the length of movies. Please output the length of the two movies in order of length. If there are multiple groups of the same length, select the one which contains the longest single moive.It is guarantee that there is a least one solution.

Example
Given t=87,dur=[20,25,19,37],return[20,37]

Explanation:
87-30=57
20+25=45,57-45=12
20+19=39,57-39=19
20+37=57,57-57=0
25+19=44,57-44=13
25+37=62,57<62
19+37=56,57-56=1
Givent=67,dur=[20,17,19,18],return[17,20]

Explanation:
67-30=37
17+20=37,18+19=37
The longest movie in the first group is 20,and 19 in the second grouo, so output[17,20]
Notice
30<t<=1000
dur[i]<=1000
1<=len(dur)<=100000

解法:双指针法。

class Solution {
public:
    /**
     * @param t: the length of the flight
     * @param dur: the length of movies 
     * @return: output the lengths of two movies
     */
    vector<int> aerial_Movie(int t, vector<int> &dur) {
        int len = dur.size();
        sort(dur.begin(), dur.end());
        int target = t - 30;
        int p1 = 0, p2 = len - 1;
        int minGap = INT_MAX;
        vector<int> result(2, 0);
        
        while (p1 < p2) {
            int sum = dur[p1] + dur[p2];
            if (sum > target) {
                p2--;
            } else if (sum == target) {
                result[0] = dur[p1];
                result[1] = dur[p2];
                return result;
            } else {
                int gap = target - sum;
                if (minGap > gap) {
                    minGap = gap;
                    result[0] = dur[p1];
                    result[1] = dur[p2];
                }
                p1++;
            }
        } 
        return result;
    }
};

二刷:

class Solution {
public:
    /**
     * @param t: the length of the flight
     * @param dur: the length of movies 
     * @return: output the lengths of two movies
     */
    vector<int> aerialMovie(int t, vector<int> &dur) {
        int n = dur.size();
        sort(dur.begin(), dur.end());
        int target = t - 30;
        int left = 0, right = n - 1;
        int minDiff = INT_MAX, minLeft = -1, minRight = -1;
        while (left < right) {
            int sum = dur[left] + dur[right];
            if (sum < target) {
                int diff = target - sum;
                if (diff < minDiff) {
                    minDiff = diff;
                    minLeft = left;
                    minRight = right;
                } else if (minDiff == diff) {
                    if (right >= minRight) {
                        minLeft = left;
                        minRight = right;
                    }
                }
                left++;
            } else if (sum > target) {
                right--;
            } else {
                if (minDiff > 0) {
                    minDiff = 0;
                    minLeft = left;
                    minRight = right;
                }
                left++;
                right--;
            }
        }
        return {dur[minLeft], dur[minRight]};
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值