Create Maximum Number
2016-07-22 04:15
369 查看
Given two arrays of length
Example
Given nums1 =
return
Given nums1 =
return
Given nums1 =
return
分析:http://bookshadow.com/weblog/2015/12/24/leetcode-create-maximum-number/
问题可以转化为这样的两个子问题:
枚举nums1子数组与nums2子数组的长度len1, len2,在满足长度之和len1+len2等于k的前提下,分别求解最大子数组,并进行合并。
然后从合并得到的子数组中取最大数组即为所求。
还有一个自己的想法,但是代码通不过,擦!
分析: 其实数字有个很好的特点,只要在剩余的数字里取一个最大的数,放在当前位置上,那么我们就可以肯定,不肯能有比当前数更大的了。 比如: 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的值会不断减少。
mand
nwith digits
0-9representing two numbers. Create the maximum number of length
k <= m + nfrom digits of the two. The relative order of the digits from the same array must be preserved. Return an array of the
kdigits. 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的前提下,分别求解最大子数组,并进行合并。
然后从合并得到的子数组中取最大数组即为所求。
public class Solution { public int[] maxNumber(int[] nums1, int[] nums2, int k) { if (nums1 == null || nums2 == null || k < 1) return new int[0]; if (nums1.length + nums2.length < k) return new int[0]; int[] tempMax = new int[k]; for (int i = 0; i <= k; i++) { if (nums1.length >= i && nums2.length >= (k - i)) { int[] max1 = maxValueAndIndex(nums1, i); int[] max2 = maxValueAndIndex(nums2, k - i); int[] arr = merge(max1, max2); if (compare(arr, tempMax)) { tempMax = arr; } } } return tempMax; } public boolean compare(int[] arr, int[] tempMax) { for (int i = 0; i < arr.length; i++) { if (arr[i] < tempMax[i]) { return false; } else if (arr[i] > tempMax[i]) { return true; } } return false; } public int[] merge(int[] arr1, int[] arr2) { int[] arr = new int[arr1.length + arr2.length]; int k = 0, p = 0, q = 0; while (p < arr1.length || q < arr2.length) { if (p >= arr1.length || q < arr2.length && arr1[p] < arr2[q]) { arr[k] = arr2[q]; q++; } else if (q >= arr2.length || p < arr1.length && arr1[p] > arr2[q]) { arr[k] = arr1[p]; p++; } else { if (isGreater(arr1, p, arr2, q)) { arr[k] = arr1[p]; p++; } else { arr[k] = arr2[q]; q++; } } k++; } return arr; } public boolean isGreater(int[] arr1, int p, int[] arr2, int q) { while (p < arr1.length || q < arr2.length) { if (q >= arr2.length || p < arr1.length && arr1[p] > arr2[q]) { return true; } else if (p >= arr1.length || q < arr2.length && arr1[p] < arr2[q]) { return false; } else { p++; q++; } } return true; } public int[] maxValueAndIndex(int[] arr, int k) { int[] nums = new int[k]; if (k == 0) return nums; int p = -1; for (int i = 0; i < arr.length; i++) { while (p >= 0 && nums[p] < arr[i] && (arr.length - i + p + 1) > k) { p--; } if (p == nums.length - 1) continue; p++; nums[p] = arr[i]; } return nums; } }
还有一个自己的想法,但是代码通不过,擦!
分析: 其实数字有个很好的特点,只要在剩余的数字里取一个最大的数,放在当前位置上,那么我们就可以肯定,不肯能有比当前数更大的了。 比如: 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的值会不断减少。
public class Solution { public static void main(String[] args) { 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, 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, 5, 3, 3, 8, 2, 2, 7, 6, 7, 5, 9, 1, 2 }; 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, 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, 0, 1, 3, 9, 1, 2, 2, 6, 6, 9, 3, 6, 0 }; Solution s = new Solution(); int[] max = s.maxNumber(arr1, arr2, 80); for (int i = 0; i < max.length; i++) { System.out.println(max[i]); } } public int[] maxNumber(int[] nums1, int[] nums2, int k) { if (nums1 == null || nums2 == null || k < 1) return new int[0]; if (nums1.length + nums2.length < k) return new int[0]; int p = 0; int q = 0; int[] maxNum = new int[k]; while (k > 0) { int[] max1 = maxValueAndIndex(nums1, p, k - (nums2.length - q)); int[] max2 = maxValueAndIndex(nums2, q, k - (nums1.length - p)); if (max1[0] > max2[0]) { maxNum[maxNum.length - k] = max1[0]; p = max1[1] + 1; } else if (max1[0] == max2[0]) { if (chooseNums1(nums1, p + 1, nums2, q + 1, k - 2)) { maxNum[maxNum.length - k] = max1[0]; p = max1[1] + 1; } else { maxNum[maxNum.length - k] = max2[0]; q = max2[1] + 1; } } else { maxNum[maxNum.length - k] = max2[0]; q = max2[1] + 1; } k--; } return maxNum; } // chose nums1 or not public boolean chooseNums1(int[] nums1, int p, int[] nums2, int q, int k) { if (p == nums1.length && q == nums2.length) { return true; } else if (p == nums1.length) { return false; } else if (q == nums2.length) { return true; } else if (k <= 0) { return true; } else { int[] max1 = maxValueAndIndex(nums1, p, k - (nums2.length - q)); int[] max2 = maxValueAndIndex(nums2, q, k - (nums1.length - p)); if (max1[0] > max2[0]) { return true; } else if (max1[0] == max2[0]) { return chooseNums1(nums1, p + 1, nums2, q + 1, k - 2); } else { return false; } } } public int[] maxValueAndIndex(int[] arr, int start, int k) { int[] max = new int[2]; if (start == arr.length) { max[0] = -1; max[1] = start; return max; } max[0] = arr[start]; max[1] = start; while (start < arr.length && arr.length - start >= k) { if (arr[start] > max[0]) { max[0] = arr[start]; max[1] = start; } start++; } return max; } }
相关文章推荐
- Android客户端登录注册模块
- 210. Course Schedule II
- wordpress数据库配置文件wp-config.php
- 浅谈android中的自定义封装易用的Dialog
- 209. Minimum Size Subarray Sum
- Visual Studio 2012 trial version
- 树状数组
- LeetCode--No.235--Lowest Common Ancestor of a Binary Search Tree
- Codeforces Round #325 (Div. 2)ABC
- LeetCode--No.110--Balanced Binary Tree--待完善
- 二分查找
- GNUPLOT linespoints and save as pdf
- OSG3.4.0+VS2013编译与设置
- Android插件化
- Devstack单节点环境实战配置
- [Angular 2] ROUTING IN ANGULAR 2 REVISITED
- 所有数位相加
- Android开发方法数超过65535的解决办法
- 风雨20年:我所积累的20条编程经验
- python之路 线程、进程、协程、队列、python-memcache、python-redis