首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >LeetCode 321. 拼接最大数(单调栈)*

LeetCode 321. 拼接最大数(单调栈)*

作者头像
Michael阿明
发布2021-02-19 15:14:43
发布2021-02-19 15:14:43
4180
举报

文章目录

1. 题目

给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。

现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序

求满足该条件的最大数。结果返回一个表示该最大数的长度为 k 的数组。

说明: 请尽可能地优化你算法的时间和空间复杂度。

代码语言:javascript
复制
示例 1:
输入:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
输出:
[9, 8, 6, 5, 3]

示例 2:
输入:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
输出:
[6, 7, 6, 0, 4]

示例 3:
输入:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
输出:
[9, 8, 9]

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/create-maximum-number 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

采用动态规划,long long 存不下,溢出,采用string,超时

代码语言:javascript
复制
class Solution {
public:
    vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
    	int m = nums1.size(), n = nums2.size();
        typedef long long ll;
    	vector<vector<vector<ll>>> dp(k+1, vector<vector<ll>>(m+1, vector<ll>(n+1, -1)));
    	dp[0][0][0] = 0;
        string str;
    	for(int t = 1; t <= k; t++) 
    	{
    		for(int i = 0; i <= m; i++)
    		{                
    			for(int j = 0; j <= n; j++)
    			{
    				if(dp[t-1][i][j] == -1)
    					continue;
    				if(i < m)
    				{
    					dp[t][i+1][j] = max(dp[t][i+1][j], dp[t-1][i][j]*10+nums1[i]);
                        dp[t-1][i+1][j] = max(dp[t-1][i+1][j], dp[t-1][i][j]);
    				}                    
    				if(j < n)
    				{
    					dp[t][i][j+1] = max(dp[t][i][j+1], dp[t-1][i][j]*10+nums2[j]);
                        dp[t-1][i][j+1] = max(dp[t-1][i][j+1], dp[t-1][i][j]);
    				}
    			}
    		}
    	}
    	vector<int> ans(k, 0);
    	ll res = 0;
        for(int i = 0; i <= m; ++i)
        {
            for(int j = 0; j <= n; ++j)
                res = max(res, dp[k][i][j]);
        }
    	for(int i = k-1; i >= 0; --i)
        {
            ans[i] = res%10;
            res /= 10;
        }
    	return ans;
    }
};

string 超时

代码语言:javascript
复制
class Solution {
public:
    vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
    	int m = nums1.size(), n = nums2.size();
    	vector<vector<vector<string>>> dp(k+1, vector<vector<string>>(m+1, vector<string>(n+1, "#")));
    	dp[0][0][0] = "/";
        string str;
    	for(int t = 1; t <= k; t++) 
    	{
    		for(int i = 0; i <= m; i++)
    		{                
    			for(int j = 0; j <= n; j++)
    			{
    				if(dp[t-1][i][j] == "#")
    					continue;  
    				if(i < m)
    				{
                        str = to_string(nums1[i]);
    					dp[t][i+1][j] = max(dp[t][i+1][j], dp[t-1][i][j]+str);
                        dp[t-1][i+1][j] = max(dp[t-1][i+1][j], dp[t-1][i][j]);
    				}                    
    				if(j < n)
    				{
                        str = to_string(nums2[j]);
    					dp[t][i][j+1] = max(dp[t][i][j+1], dp[t-1][i][j]+str);
                        dp[t-1][i][j+1] = max(dp[t-1][i][j+1], dp[t-1][i][j]);
    				}
    			}
    		}
    	}
    	vector<int> ans(k, 0);
    	string res = "";
        for(int i = 0; i <= m; ++i)
        {
            for(int j = 0; j <= n; ++j)
                res = max(res, dp[k][i][j]);
        }
    	for(int i = 0; i < k; ++i)
            ans[i] = res[i+1]-'0';
    	return ans;
    }
};
代码语言:javascript
复制
class Solution {
    vector<int> tmp;
public:
    vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
        int n1 = nums1.size(), n2 = nums2.size();
        tmp.resize(k);
        int r = min(n1, k);
        vector<int> ans;
        for(int i = 0; i <= r; ++i)
        {
            if(k-i > n2)
                continue;
            auto arr1 = select(nums1, i);
            auto arr2 = select(nums2, k-i);
            merge(arr1, arr2, ans);
        }
        return ans;
    }
    vector<int> select(vector<int>& nums, int k)
    {
        if(k == nums.size())
            return nums;
        vector<int> stk;
        for(int i = 0; i < nums.size(); ++i)
        {
            while(!stk.empty() && stk.size()+nums.size()-i > k && stk.back() < nums[i])
                stk.pop_back();
            stk.push_back(nums[i]);
        }
        stk.resize(k);
        return stk;
    }
    void merge(vector<int>& a1, vector<int>& a2, vector<int>& ans)
    {
        int n1 = a1.size(), n2 = a2.size(), i = 0, j = 0, idx = 0;
        while(i < n1 && j < n2)
        {
            if(compare(a1, i, a2, j) >= 0)
                tmp[idx++] = a1[i++];
            else
                tmp[idx++] = a2[j++];
        }
        while(i < n1)
            tmp[idx++] = a1[i++];
        while(j < n2)
            tmp[idx++] = a2[j++];
        if(ans.empty())
            ans = tmp;
        else if(ans < tmp)
            ans = tmp;
    }
    int compare(vector<int>& a1, int i, vector<int>& a2, int j)
    {
        int n1 = a1.size(), n2 = a2.size();
        while(i < n1 && j < n2)
        {
            int diff = a1[i] - a2[j];
            if(diff != 0)
                return diff;
            i++,j++;
        }
        return (n1-i)-(n2-j);//相等话,有剩余的先取
    }
};

144 ms 20.6 MB C++


本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/12/03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 1. 题目
  • 2. 解题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档