LeetCode 354. Russian Doll Envelopes

来源:互联网 发布:手机声音扩大软件 编辑:程序博客网 时间:2024/05/16 11:52

题目:

You have a number of envelopes with widths and heights given as a pair of integers (w, h). One envelope can fit into another if and only if both the width and height of one envelope is greater than the width and height of the other envelope.

What is the maximum number of envelopes can you Russian doll? (put one inside other)

Example:
Given envelopes = [[5,4],[6,4],[6,7],[2,3]], the maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]).

大意就是给出一堆信封,用一封信装其他信封,有这么一个信封,它能装的信封数是所有信封中最多的,求出这个信封最多可以装的信封数量


思路和解法:

先用信封的宽度进行排序,然后找出第i封信能装的最大信封数,记为d[i],比较d[i]和当前最大的信封书maxlen后更新maxlen。

排序使用非递归的归并排序,不详述。找第i个信封能装的最大信封数用动态规划。假设第i个信封为A,并且A前的i-1个信封可装最大信封数已知。那么从这i-1个信封中选出可以被A装入的所有信封,在从刚刚选出的信封中选出装了最多信封的信封B,那么A可以装入的最大信封数就是B可装入信封数加1。

j<i,如果第j个信封可以装进第i个信封,即第j个信封的长宽都小于第i个信封,则检查d[i]是否小于d[j]+1,若是,d[i] = d[j] + 1。


代码:

<pre name="code" class="cpp" style="color: rgb(51, 51, 51); font-size: 14px;">#include<iostream>#include<vector>using namespace std;void sortEnvlps(vector<pair<int, int> > &e);class Solution {public:    int maxEnvelopes(vector<pair<int, int> >& envelopes) {        //如果数组为零,返回0        if(envelopes.size() == 0)            return 0;        //根据每对数的第一位排序,降序        sortEnvlps(envelopes);        int d[envelopes.size()], maxlen = 1;        d[0] = 1;        for(int i = 1; i < envelopes.size(); i++)        {            d[i] = 1;            for(int j = i-1; j >=0; j--)            {                //如果第i封信可以装下第j封信                if(envelopes[i].first > envelopes[j].first && envelopes[i].second > envelopes[j].second)                {                    //检查更新第i封信能装下的最大信封数                    if(d[i] < d[j]+1)                    {                        d[i] = d[j]+1;                        //如果第i封信的最大信封数已经比前面所有信封                        //能装的最大信封数都大,就跳出循环,去找第i+1封信能装下的最大信封数                        if(d[i] > maxlen)                            break;                    }                }            }            //检查更新当前装的最多的信封数            if(d[i] > maxlen)                maxlen = d[i];        }        return maxlen;    }};//排序函数void sortEnvlps(vector<pair<int, int> > &e){int lhead, ltail, rhead, rtail, pos = 0;vector<pair<int,int> > rec(e.size(),make_pair(0,0));for(int i = 1; i < e.size(); i*=2){lhead = 0;while(lhead < e.size()-i){pos = 0;ltail = lhead+i;//左边数组的右边界rhead = ltail;//右边数组的左边界rtail = rhead+i>e.size() ? e.size():rhead+i;//右边数组的右边界,要注意超过原数组长度//记录要放到左边数组的数while(lhead<ltail && rhead<rtail){if(e[lhead].first > e[rhead].first){rec[pos].first = e[rhead].first;rec[pos].second = e[rhead].second;rhead++;}else{rec[pos].first = e[lhead].first;rec[pos].second = e[lhead].second;lhead++;}pos++;}while(lhead < ltail){e[--rhead] = e[--ltail];}while(pos-- > 0){e[--rhead] = rec[pos];}lhead = rtail;}}rec.clear();}




时间复杂度分析:

归并排序复杂度为O(nlogn),排序后找最大信封数的复杂度为O(n^2),所以总的复杂度为O(n^2)。


0 0
原创粉丝点击