leetcode 354. Russian Doll Envelopes & leetcode 300 Longest Increasing Subsequence

56 篇文章 0 订阅
53 篇文章 0 订阅

前言

两道思路基本一样的动态规划的题目,354 俄罗斯套娃这题稍微绕了一些,但基本思路跟300一样。

leetcode 354 Russian Doll Envelopes

题目描述

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]).

思路分析

看到pair我们很容易想到排序,然后一个想当然的解法就是贪婪了,从最后开始选,选择局部最优直到数组0下标位置,似乎隐隐觉得哪里不对~我们知道,贪心的一个很重要的判定:局部最优是否能够达到全局最优。很明显对于这道题,我们无法达到全局最优。因为按照width的排序结果,很可能有一个不是最优的较大的width对应的pair排在靠后的位置,例如:[3,8],[5,9],[6,7],[8,10] 按照贪婪算法,我们选择了[8,10],[6,7], 然而,很明显最优解是[8,10],[5,9],[3,8]。贪婪算法不适用于本题的情况。贪婪不适用的情况下,一般我们都会考虑它的相似解法:动态规划。我们假设仍是按宽度得到的排序结果,第i个位置处能够包含的pair最大数量满足这样的状态转移方程:
dp[i] = max(dp[i],max(dp[j])+1). j>=0,j < i.

根据状态转移方程,我们可以写出对应的AC解:

代码实现

class Solution {
public:
    int maxEnvelopes(vector<pair<int, int>>& envelopes) {
        //贪婪算法?不可解
        //dp 排序的第一步没做错
        if(envelopes.size()<=1) return envelopes.size();
        sort(envelopes.begin(),envelopes.end(),[](const pair<int,int>& lhs,const pair<int,int> &rhs)->int {

            return lhs.first<rhs.first;
        });
        int size = envelopes.size();
        vector<int> dp(size,1);
        int ret = 0;
        for(int i = 0;i<size;++i) {
            auto iVal = envelopes[i];
            for(int j = i-1;j>=0;--j) {
                auto val = envelopes[j];
                if(val.second<iVal.second&&val.first<iVal.first&&dp[i]<dp[j]+1) {
                    dp[i] = dp[j]+1;
                }
            }
            ret = max(ret,dp[i]);
        }
        return ret;
    }
};

leetcode 300 Longest Increasing Subsequence

题目描述

Given an unsorted array of integers, find the length of longest increasing subsequence.

For example,
Given [10, 9, 2, 5, 3, 7, 101, 18],
The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length.

Your algorithm should run in O(n2) complexity.

Follow up: Could you improve it to O(n log n) time complexity?

思路分析

这次我们要找一个最长递增序列,跟上题同样的道理,我们采用动态规划的方式解决本题,状态转移方程基本不变,我们暂且不考虑O(nlogn)的时间复杂度要求,关于时间复杂度的优化,我们会在接下来的改进中解决。

代码实现

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> dp(nums.size(),1);
        for(int i =1;i<nums.size();++i)
            for(int j = 0;j<i;++j) {
                if(nums[j]<nums[i]&&(dp[i]<(dp[j]+1))) {
                    dp[i] = dp[j]+1;
                }
            }

        int maxLen = 0;
        for(int i = 0;i<dp.size();++i) {
            maxLen = max(maxLen,dp[i]);
        }
        return maxLen;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值