標籤:
題目分析:
給定兩個長度分別為m和n的數組,數組元素為0-9,每個數組元素代表一個數字。從這兩個數組中選出一些數字,組成一個數組,是這個數組中的數儘可能大,其長度k <= m + n。要求數組中選出的元素的相對順序與原數組保持一致。最終返回一個包含k個數位數組。
解題思路:
1)分別從nums1(長度為m)和nums2(長度為n)中挑選出i(max(0, k - n) <= i <= min(m, k) 和k-i個數,在保持挑選數組的元素相對順序不變的情況下,使選出的子數組最大化,主要利用貪心演算法進行選取;
2)在保持元素相對位置不變的前提下,將數組nums1與nums2合并,使合并的數組最大化。
實現程式
C++版本
// 貪心求數組中的最大子數組 vector<int> findMaxKValue(vector<int> &nums, int k){ vector<int> result; if (k == 0) return result; result = vector<int>(k, 0); int j = 0; int n = nums.size(); for (int i = 0; i < n; i++) { // 出棧操作 while (j > 0 && n - i + j > k && nums[i] > result[j - 1]) j--; // 入棧操作 if (j < k) result[j++] = nums[i]; } return result;}// merge操作中的對比函數 bool compare(vector<int> &result1, int i, vector<int> &result2, int j){ while (i < result1.size() && j < result2.size() && result1[i] == result2[j]) { i++; j++; } return j == result2.size() || (i < result1.size() && result1[i] > result2[j]);}// 兩個數組的merge操作 vector<int> merge(vector<int> &nums1, vector<int> &nums2){ int m = nums1.size(); int n = nums2.size(); if (!m) return nums2; if (!n) return nums1; vector<int> result(m + n, 0); int i = 0; int j = 0; int k = 0; // 數組合併作業 while (i < m || j < n) { result[k++] = compare(nums1, i, nums2, j) ? nums1[i++] : nums2[j++]; } return result;}// 返回兩個數組中最大的k個數,並保持每個數組中的元素相對位置不變 vector<int> maxNumber(vector<int> &nums1, vector<int> &nums2, int k){ int m = nums1.size(); int n = nums2.size(); vector<int> result(k, 0); // 從數組nums中挑選k個數,在保持元素相對順序不變的情況下,使得選出的子數組最大化。 for (int i = max(0, k - n); i <= min(m, k); i++) { // 在數組nums1中挑選i個數 vector<int> result1 = findMaxKValue(nums1, i); // 在數組nums2中挑選k-i個數 vector<int> result2 = findMaxKValue(nums2, k - i); // 將兩個挑選出的子數組進行合并 vector<int> temp = merge(result1, result2); // 比較大小,來判斷是否更新數組 if (compare(temp, 0, result, 0)) result = temp; } return result;}
Java版本
private boolean compare(int[] result1, int pos1, int[] result2, int pos2) { for ( ; pos1 < result1.length && pos2 < result2.length; pos1++, pos2++){ if (result1[pos1] > result2[pos2]) return true; if (result1[pos1] < result2[pos2]) return false; } return pos1 != result1.length;}private int[] findMaxKValue(int[] nums, int k) { int[] result = new int[k]; int len = 0; for (int i = 0; i < nums.length; i++){ while (len > 0 && len + nums.length - i > k && result[len - 1] < nums[i]){ len--; } if (len < k) result[len++] = nums[i]; } return result;}public int[] maxNumber(int[] nums1, int[] nums2, int k){ int[] result = new int[k]; for (int i = Math.max(k - nums2.length, 0); i <= Math.min(nums1.length, k); i++){ int[] result1 = findMaxKValue(nums1, i); int[] result2 = findMaxKValue(nums2, k - i); // 對兩個數組執行merge操作 int[] temp = new int[k]; int pos1 = 0; int pos2 = 0; int tpos = 0; while (pos1 < result1.length || pos2 < result2.length){ temp[tpos++] = compare(result1, pos1, result2, pos2) ? result1[pos1++] : result2[pos2++]; } if (!compare(result, 0, temp, 0)) result = temp; } return result;}
參考文獻
http://bookshadow.com/weblog/2015/12/24/leetcode-create-maximum-number/
http://blog.csdn.net/murmured/article/details/50392234
leetcode_321 Create Maximum Number