leetcode 321 Create Max Number
leetcode 321 Create Max Number
greedy的方法,由於有兩個數組,我們很自然的想到從數組1中選i個數,數組2中選k-i個數,這樣我們只需要遍歷max(0, k-數組2長度n) ~ 數組1長度,然後保存合並i和k-i這兩個部分之後得到的最大值即可。 那麽還剩下這幾個問題:
1) 從一個數組中不改變元素順序地選出i個元素,使他們順序排列代表的十進制數最大。例:[1,4,3,6,2], i = 3, 結果為[4,6,2]
2) 如何合並數組1的i個元素和數組2的k-i個元素
3) 比較兩個數組所代表的十進制數的大小
第一個問題,我們需要使用棧的概念,遍歷數組,每次比較棧頂元素與當前元素i,若i比棧頂元素大,則pop棧頂,繼續比較,直到棧空或者i比棧頂元素小。註意,我們還需要時刻檢測,i之後的元素是否足夠補上pop出棧的空缺,若不夠則不能再pop。例:[1,4,3,6,2], 當index為3時,棧中有[4,3],6和3比,大於,彈出3,繼續比4,大於,這時候卻不能彈出4,因為6後面只有一個數,不夠補上pop2次的空缺。
第二個問題,分別用兩個index i, j指向數組1和2,比較他們指向的元素,將大的元素放入新的大小為k的數組。註意,如何比較呢?可能指向元素相等,可能某一個數組已經到頭了。詳細過程在第三個問題列出
第三個問題,如何比較?本題有兩個地方需要使用比較,第一個就是主函數中比較不同i值導致的不同長度為k的數組,這個較為簡單,因為兩個數組長度一致,只需要用兩個index,i,j分別遍歷兩個數組即可,返回nums1[i]和nums2[j]中較大的那一個,若相等則i++,j++,若i=j=k-1還是相等,說明兩個數組代表的十進制數相同,返回哪一個都可以。第二個地方就是上一個問題中提到的,比較兩個index指向元素的大小,一部分與之前解法相同,元素相等就繼續比較後面的元素,不過有一點需要區別的,這裏的兩個數組可能是不同長度的,所以有可能i或j中某一個指向的位置沒有數組元素,即這個數組已經到頭了,這種情況,顯然就可以返回另一個數組的index指向的元素。
代碼如下:
1 class Solution { 2 public int[] maxNumber(int[] nums1, int[] nums2, int k) { 3 int len1 = nums1.length, len2 = nums2.length; 4 int[] res = new int[k]; 5 6 for(int i=0; i<=k; i++){ 7 if((k - i) <= len2 && i <= len1){8 int[] tmp = new int[k]; 9 tmp = merge(singleNum(nums1, i), singleNum(nums2, k-i)); 10 if(compare(tmp, 0, res, 0)) 11 res = tmp; 12 } 13 } 14 15 return res; 16 } 17 18 public int[] singleNum(int[] nums, int k){ 19 int len = nums.length; 20 int[] res = new int[k]; 21 int j = 0; 22 23 for(int i=0; i<len; i++){ 24 25 while(len-i+j > k && j > 0 && res[j-1] < nums[i]) 26 j--; 27 if(j < k) 28 res[j++] = nums[i]; 29 } 30 return res; 31 32 } 33 34 public int[] merge(int[] nums1, int[] nums2){ 35 int k = nums1.length + nums2.length; 36 int[] res = new int[k]; 37 38 for(int i=0, j=0, idx = 0; idx < k; idx++){ 39 res[idx] = compare(nums1, i, nums2, j) ? nums1[i++] : nums2[j++]; 40 } 41 return res; 42 43 } 44 45 private boolean compare(int[] nums1, int idx1, int[] nums2, int idx2){ 46 while(idx1 < nums1.length && idx2 < nums2.length && nums1[idx1] == nums2[idx2]){ 47 idx1++; 48 idx2++; 49 } 50 return idx2 == nums2.length || (idx1 < nums1.length && nums1[idx1] > nums2[idx2]); 51 52 } 53 }
leetcode 321 Create Max Number