标签:
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. You should try to optimize your time and space complexity.
Given nums1 = [3, 4, 6, 5]
, nums2 = [9, 1, 2, 5, 8, 3]
, k = 5
return [9, 8, 6, 5, 3]
Given nums1 = [6, 7]
, nums2 = [6, 0, 4]
, k = 5
return [6, 7, 6, 0, 4]
Given nums1 = [3, 9]
, nums2 = [8, 9]
, k = 3
return [9, 8, 9]
分析:http://bookshadow.com/weblog/2015/12/24/leetcode-create-maximum-number/
问题可以转化为这样的两个子问题:
1. 从数组nums中挑选出t个数,在保持元素相对顺序不变的情况下,使得选出的子数组最大化。 2. 在保持元素相对顺序不变的前提下,将数组nums1与数组nums2合并,使合并后的数组最大化。
枚举nums1子数组与nums2子数组的长度len1, len2,在满足长度之和len1+len2等于k的前提下,分别求解最大子数组,并进行合并。
然后从合并得到的子数组中取最大数组即为所求。
1 public class Solution { 2 3 public static void main(String[] args) { 4 int[] arr1 = { 6, 7 }; 5 int[] arr2 = { 6, 0, 4 }; 6 Solution s = new Solution(); 7 int[] max = s.maxNumber(arr1, arr2, 5); 8 9 for (int i = 0; i < max.length; i++) { 10 System.out.println(max[i]); 11 } 12 } 13 14 public int[] maxNumber(int[] nums1, int[] nums2, int k) { 15 if (nums1 == null || nums2 == null || k < 1) 16 return new int[0]; 17 if (nums1.length + nums2.length < k) 18 return new int[0]; 19 int[] tempMax = new int[k]; 20 21 for (int i = 0; i <= k; i++) { 22 if (nums1.length >= i && nums2.length >= (k - i)) { 23 int[] max1 = maxValueAndIndex(nums1, i); 24 int[] max2 = maxValueAndIndex(nums2, k - i); 25 int[] arr = merge(max1, max2); 26 27 if (compare(arr, tempMax)) { 28 tempMax = arr; 29 } 30 } 31 } 32 return tempMax; 33 } 34 35 public boolean compare(int[] arr, int[] tempMax) { 36 for (int i = 0; i < arr.length; i++) { 37 if (arr[i] < tempMax[i]) { 38 return false; 39 } else if (arr[i] > tempMax[i]) { 40 return true; 41 } 42 } 43 return false; 44 } 45 46 public int[] merge(int[] arr1, int[] arr2) { 47 int[] arr = new int[arr1.length + arr2.length]; 48 int k = 0; 49 int p = 0; 50 int q = 0; 51 52 while (p < arr1.length && q < arr2.length) { 53 if (arr1[p] < arr2[q]) { 54 arr[k] = arr2[q]; 55 q++; 56 } else if (arr1[p] > arr2[q]) { 57 arr[k] = arr1[p]; 58 p++; 59 } else { 60 if (isGreater(arr1, p, arr2, q)) { 61 arr[k] = arr1[p]; 62 p++; 63 } else { 64 arr[k] = arr2[q]; 65 q++; 66 } 67 } 68 k++; 69 } 70 71 while (p < arr1.length) { 72 arr[k] = arr1[p]; 73 p++; 74 k++; 75 } 76 77 while (q < arr2.length) { 78 arr[k] = arr2[q]; 79 q++; 80 k++; 81 } 82 83 return arr; 84 } 85 86 public boolean isGreater(int[] arr1, int p, int[] arr2, int q) { 87 while (p < arr1.length && q < arr2.length) { 88 if (arr1[p] == arr2[q]) { 89 p++; 90 q++; 91 } else if (arr1[p] > arr2[q]) { 92 return true; 93 } else { 94 return false; 95 } 96 } 97 98 if (p == arr1.length && q == arr2.length) { 99 return true; 100 } else if (p == arr1.length) { 101 return false; 102 } else { 103 return true; 104 } 105 106 } 107 108 public int[] maxValueAndIndex(int[] arr, int k) { 109 int p = -1; 110 int[] nums = new int[k]; 111 if (k == 0) 112 return nums; 113 114 for (int i = 0; i < arr.length; i++) { 115 if (p == -1) { 116 p++; 117 nums[p] = arr[i]; 118 } else if (nums[p] < arr[i] && (arr.length - i + p + 1) > k) { 119 while (p >= 0 && nums[p] < arr[i] && (arr.length - i + p + 1) > k) { 120 p--; 121 } 122 p++; 123 nums[p] = arr[i]; 124 } else if (p != nums.length - 1) { 125 p++; 126 nums[p] = arr[i]; 127 } 128 } 129 return nums; 130 } 131 }
还有一个自己的想法,但是代码通不过,擦!
分析: 其实数字有个很好的特点,只要在剩余的数字里取一个最大的数,放在当前位置上,那么我们就可以肯定,不肯能有比当前数更大的了。 比如: xx_ _ _, x表示那个位置上已经被填入数字了,那么从5, 2, 1,7,3中,找出一个,使得组合最大,你会毫不犹豫的选择7,因为如果你不选7,不管后面你把7放在哪个位置,都比放7的情况更小。
好了,有了这个基础,解决下面这题就简单了。
从两个数组中,我们一定要找一个最大的出来放在首位(根据我们上面的分析),但是,这里有个条件,就是从每个数组里取的数,不能倒着取,如果你从nums1取了6,不好意思,下次你就不能取3,或者4了。
那么,我们怎么取才能保证最大,而且,并且剩余可取数字的个数还必须至少是K呢,这个好像就很简单了吧。
用两个指针,p, q 分别指到两个数组的头部,表面两个指针后面的数字是可取的,前面的不行,当我们从两个数组里找最大数字的时候,我们只需要保证 (nums1.length - p1) + (nums2.length - q) >= k (最大值在nums1) 或者 (nums1.length - p) + (nums2.length - q1) >= k (最大值在nums2). 这里k的值会不断减少。
1 public class Solution { 2 3 public static void main(String[] args) { 4 int[] arr1 = { 1, 5, 8, 1, 4, 0, 8, 5, 0, 7, 0, 5, 7, 6, 0, 5, 5, 2, 4, 3, 6, 4, 6, 6, 3, 8, 1, 1, 3, 1, 3, 5, 5 4, 3, 9, 5, 0, 3, 8, 1, 4, 9, 8, 8, 3, 4, 6, 2, 5, 4, 1, 1, 4, 6, 5, 2, 3, 6, 3, 5, 4, 3, 0, 7, 2, 5, 1, 6 5, 3, 3, 8, 2, 2, 7, 6, 7, 5, 9, 1, 2 }; 7 int[] arr2 = { 7, 8, 5, 8, 0, 1, 1, 6, 1, 7, 6, 9, 6, 6, 0, 8, 5, 8, 6, 3, 4, 0, 4, 6, 7, 8, 7, 7, 7, 5, 7, 2, 8 5, 2, 1, 9, 5, 9, 3, 7, 3, 9, 9, 3, 1, 4, 3, 3, 9, 7, 1, 4, 4, 1, 4, 0, 2, 3, 1, 3, 2, 0, 2, 4, 0, 9, 2, 9 0, 1, 3, 9, 1, 2, 2, 6, 6, 9, 3, 6, 0 }; 10 Solution s = new Solution(); 11 int[] max = s.maxNumber(arr1, arr2, 80); 12 13 for (int i = 0; i < max.length; i++) { 14 System.out.println(max[i]); 15 } 16 } 17 18 public int[] maxNumber(int[] nums1, int[] nums2, int k) { 19 if (nums1 == null || nums2 == null || k < 1) 20 return new int[0]; 21 if (nums1.length + nums2.length < k) 22 return new int[0]; 23 int p = 0; 24 int q = 0; 25 26 int[] maxNum = new int[k]; 27 28 while (k > 0) { 29 int[] max1 = maxValueAndIndex(nums1, p, k - (nums2.length - q)); 30 int[] max2 = maxValueAndIndex(nums2, q, k - (nums1.length - p)); 31 32 if (max1[0] > max2[0]) { 33 maxNum[maxNum.length - k] = max1[0]; 34 p = max1[1] + 1; 35 } else if (max1[0] == max2[0]) { 36 if (chooseNums1(nums1, p + 1, nums2, q + 1, k - 2)) { 37 maxNum[maxNum.length - k] = max1[0]; 38 p = max1[1] + 1; 39 } else { 40 maxNum[maxNum.length - k] = max2[0]; 41 q = max2[1] + 1; 42 } 43 } else { 44 maxNum[maxNum.length - k] = max2[0]; 45 q = max2[1] + 1; 46 } 47 k--; 48 } 49 return maxNum; 50 51 } 52 53 // chose nums1 or not 54 public boolean chooseNums1(int[] nums1, int p, int[] nums2, int q, int k) { 55 if (p == nums1.length && q == nums2.length) { 56 return true; 57 } else if (p == nums1.length) { 58 return false; 59 } else if (q == nums2.length) { 60 return true; 61 } else if (k <= 0) { 62 return true; 63 } else { 64 int[] max1 = maxValueAndIndex(nums1, p, k - (nums2.length - q)); 65 int[] max2 = maxValueAndIndex(nums2, q, k - (nums1.length - p)); 66 67 if (max1[0] > max2[0]) { 68 return true; 69 } else if (max1[0] == max2[0]) { 70 return chooseNums1(nums1, p + 1, nums2, q + 1, k - 2); 71 } else { 72 return false; 73 } 74 } 75 } 76 77 public int[] maxValueAndIndex(int[] arr, int start, int k) { 78 int[] max = new int[2]; 79 if (start == arr.length) { 80 max[0] = -1; 81 max[1] = start; 82 return max; 83 } 84 max[0] = arr[start]; 85 max[1] = start; 86 87 while (start < arr.length && arr.length - start >= k) { 88 if (arr[start] > max[0]) { 89 max[0] = arr[start]; 90 max[1] = start; 91 } 92 start++; 93 } 94 return max; 95 } 96 }
标签:
原文地址:http://www.cnblogs.com/beiyeqingteng/p/5693760.html