标签:
题目分析:
给定两个长度分别为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/
leetcode_321 Create Maximum Number
标签:
原文地址:http://blog.csdn.net/yzhang6_10/article/details/51367533