[Leetcode P11]Container With Most Water

原题:

Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container and n is at least 2.

解法:
开始试着用暴力的O(n^2)去做,当然既然是medium水平的题目也不会这么简单,不过这题的思路是很直接的,秉承着尽量不看解答的原则,这个解法是我自己想到的,可能有更快的解法。
这题的一个要点就是我们要短的那条木板决定了容器的高度,所以只要当我们选择了一个木板的时候,这个木板一定是最短的就可以了,顺利地想到可以降序排序,排序后找到的木板一定是最短的。
那么问题来了,有了高度,怎么确定两个木板的距离的?也很简单,我们在排序的时候记录下标就可以了。但是我们要找到和当前的木板下标最远的那个,怎么办呢?很简单,和第k+1个木板相距最远的木板应该是前k个比较高木板的最大x坐标或者最小x坐标,遍历过程中一直做一下记录就可以了。
最后的时间复杂度是O(nlogn+n)=O(nlogn),如果你自己写桶排序的话当然也可以O(n),总之就是排序的复杂度,题目给的也就是O(nlogn),归并排序就可以,快排的话,感觉最差情况下会超时。
STL里的algorithm有很多好用的函数(最近刷题的过程中真的感受到了STL的方便之处),sort可以做到O(nlogn)排序,max/min可以直接找最大容量和最大、最小下标。我偷懒在网上找了段可以记录索引值的排序算法,也可以参考一下。
下面是代码:

template <typename T>
vector<int> sort_indexes(const vector<T> &v) {

    // 初始化索引向量
    vector<int> idx(v.size());
    for (int i = 0; i < v.size(); i++)
    {
        idx[i] = i;
    }

    // 通过比较v的值对索引idx进行排序
    sort(idx.begin(), idx.end(),
        [&v](size_t i1, size_t i2) {return v[i1] > v[i2]; });
    return idx;
}

class Solution {
public:
    int maxArea(vector<int>& height) {
        int max_area = 0;
        int len = height.size();
        if (len == 0)
        {
            return 0;
        }
        vector<int> idx = sort_indexes(height);
        int min_x = idx[0], max_x = idx[0];
        for (int i = 0; i < len; i++)
        {
            max_area = max(max_area, (int)max(fabs(idx[i] - min_x - 0.0)*height[idx[i]], fabs(idx[i] - max_x - 0.0)*height[idx[i]]));
            max_x = max(max_x, idx[i]);
            min_x = min(min_x, idx[i]);
        }
        return max_area;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值