日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時間:2024/7/5 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode 321. 拼接最大数(单调栈)* 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 1. 題目
    • 2. 解題

1. 題目

給定長度分別為 m 和 n 的兩個數(shù)組,其元素由 0-9 構(gòu)成,表示兩個自然數(shù)各位上的數(shù)字。
現(xiàn)在從這兩個數(shù)組中選出 k (k <= m + n) 個數(shù)字拼接成一個新的數(shù),要求從同一個數(shù)組中取出的數(shù)字保持其在原數(shù)組中的相對順序

求滿足該條件的最大數(shù)。結(jié)果返回一個表示該最大數(shù)的長度為 k 的數(shù)組。

說明: 請盡可能地優(yōu)化你算法的時間和空間復雜度。

示例 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
著作權(quán)歸領扣網(wǎng)絡所有。商業(yè)轉(zhuǎn)載請聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

2. 解題

采用動態(tài)規(guī)劃,long long 存不下,溢出,采用string,超時

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 超時

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;} };
  • 枚舉所有可能的長度組合 {i, k-i}
  • 從數(shù)組里取出 x 個數(shù),使之最大(單調(diào)棧法)(參考:LeetCode 5614. 找出最具競爭力的子序列(單調(diào)棧))
  • 再合并取出來的兩個數(shù)組(遇到相等的,往后找,找完了,有剩余的先取)
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++];elsetmp[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++


我的CSDN博客地址 https://michael.blog.csdn.net/

長按或掃碼關(guān)注我的公眾號(Michael阿明),一起加油、一起學習進步!

總結(jié)

以上是生活随笔為你收集整理的LeetCode 321. 拼接最大数(单调栈)*的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。