1. 程式人生 > >Leetcode題解:用字串快速解決Create Maximum Number問題

Leetcode題解:用字串快速解決Create Maximum Number問題

問題描述

Given two arrays of length m and n with digits 0-9 representing two numbers. 
Create the maximum number of length k <= m + n from digits of the two. 
The relative order of the digits from the same array must be preserved. 
Return an array of the k digits.

Note: You should try to optimize your time and space complexity.
Example 1: Input: nums1 = [3, 4, 6, 5] nums2 = [9, 1, 2, 5, 8, 3] k = 5 Output: [9, 8, 6, 5, 3] Example 2: Input: nums1 = [6, 7] nums2 = [6, 0, 4] k = 5 Output: [6, 7, 6, 0, 4] Example 3: Input: nums1 = [3, 9] nums2 = [8, 9] k = 3 Output: [9, 8, 9]

演算法設計

可以分成三大部分來考慮,首先是分別從兩個向量中提取長度為x的最大數字s1和長度為k-x的最大數字s2,之後是要將s1和s2合併成為最大的數字s3,最後是從所有可能的s3當中,抽取最大的那一個,並轉換成vector返回。

主要思想:

  • 從向量中提取某長度的最大數字使用了貪心法,因為只要一個數字的高位比另一個數字高,就一定比它要大,因此可以使用棧來不斷更新高位的值。
  • 將兩個字串合併使用了類似歸併排序的思路,每次都看兩個字串的第一個元素的值誰更大。但要注意由於字串並非是內部有序的,因此在遇到相等的情況時要一直往後找來決定選擇哪一個。

程式碼實現

class Solution {
public:

	//從num裡面求取長為k的最大值
	string get_maxnum (vector<int>& num, int k) {
		string v = "";
		char
c; if (k == 0) { return v; } v.resize(k); v[0] = char(num[0]+'0'); int j = 1; for (int i = 1; i < num.size(); i++) { c = char(num[i]+'0'); if (c > v[j-1]) { while (c > v[j-1] && num.size()-i+j > k && j > 0) { j--; } } if (j < k) { j++; v[j-1] = c; } } return v; } //獲取兩個向量按序能夠組成的最長的串 string maxnumber(string nums1, string nums2) { string s = ""; int m = nums1.size(); int n = nums2.size(); int i = 0, j = 0; for (; i < m && j < n;) { if (nums1[i] > nums2[j]) { s += nums1[i]; i++; } else if (nums1[i] < nums2[j]) { s += nums2[j]; j++; } else { int ii = i, jj = j; for(;;ii++,jj++) { if (nums1.size() == ii || nums2[jj] > nums1[ii]) { jj = ii+1; break; } if (nums2.size() == jj || nums2[jj] < nums1[ii]) { ii = jj+1; break; } } if (ii > jj) { s += nums1[i]; i++; } else { s += nums2[j]; j++; } } } return s+nums1.substr(i)+nums2.substr(j); } vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) { int m = nums1.size(); int n = nums2.size(); string max = ""; int mm = m > k ? k:m; int nn = n > k ? k:n; string temp; for (;mm >= 0; mm--) { if (mm == k) { temp = get_maxnum(nums1, mm); } else { if (k-mm <= nn) { temp = maxnumber(get_maxnum(nums1, mm), get_maxnum(nums2, k-mm)); } else { break; } } max = max < temp ? temp:max; } for (;nn >= 0; nn--) { if (nn == k) { temp = get_maxnum(nums2, nn); } else { if (k-nn <= mm) { temp = maxnumber(get_maxnum(nums2, nn), get_maxnum(nums1, k-nn)); } else { break; } } max = max < temp ? temp:max; } std::vector<int> v; for (auto c:max) { v.push_back(c-'0'); } return v; } };

這次被一個無比智障的bug坑了很久,就是我居然直接拿數字和字元比較,然後就得到了9 < '0’這種無比神奇的結果。不過也有收穫,第一次用了string的resize方法。本來以為這個演算法笨重無比,但最後居然結果還不錯。。。

在這裡插入圖片描述