码迷,mamicode.com
首页 > 其他好文 > 详细

Create Maximum Number

时间:2016-07-22 06:33:15      阅读:297      评论:0      收藏:0      [点我收藏+]

标签:

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.

Example

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 }

 

Create Maximum Number

标签:

原文地址:http://www.cnblogs.com/beiyeqingteng/p/5693760.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!