给你两个整数数组 nums1 和 nums2,它们的长度分别为 m 和 n。数组 nums1 和 nums2 分别代表两个数各位上的数字。同时你也会得到一个整数 k。
请你利用这两个数组中的数字中创建一个长度为 k <= m + n 的最大数,在这个必须保留来自同一数组的数字的相对顺序。
返回代表答案的长度为 k 的数组。
示例 1:
输入:nums1 = [3,4,6,5], nums2 = [9,1,2,5,8,3], k = 5
输出:[9,8,6,5,3]
示例 2:
输入:nums1 = [6,7], nums2 = [6,0,4], k = 5
输出:[6,7,6,0,4]
示例 3:
输入:nums1 = [3,9], nums2 = [8,9], k = 3
输出:[9,8,9]
解题思路:
1首先找一下两个数组,组成目标数组一共有几种组合。实例二为例:例如k=5,第一个数组的长度是2,第二个数组的长度是3,那么只第一个数组中选择2个数,第二个数组中选择3个数,这一种组合。若这两个数组长度都很大,那么组合就多了(0,5)(1,4)。。。(5,0)这么多组合。
2组合确定了之后,从每个组合中找到有序且最大的那一组数。以第一组示例为例:例如k=5时,在(3,2)这个组合下,第一个数组nums1 = [3,4,6,5]中选择三个数,得到最大的数组为[4,6,5],第二个数组nums2 = [9,1,2,5,8,3]中选择2个数:[9,8]。
3,将得到两个最大的数组,进行合并组成每个组合得到最大的数。将上一步的得到[4,6,5]与[9,8]合并,这是关键的一部,如何对比,并排列呢,两个数组合并,得到最大数,两个数组从左向右比较,谁大选择谁:9 8 4 6 5,以上是一般情况。如果一样大呢该如何选择呢,例如【6,6,7】与【6,6】组成最大数为66766,如果一样大,就需要看他们后面的数。
4,比较所有组合得到结果,选择最大的。每一个组合都有一个组成的数,那么就需要对比,看哪个组合得到的最大,就是结果。
代码如下:
public static int[] maxNumber(int[] nums1, int[] nums2, int k) {
int []b=new int[k+1];
//选择合适的组合,例如k=5,那么两个数组分别选出的数可以为0,5 1,4 2,3 3,2 4,1
for (int i=0;i<k+1;i++){
b[i]=i;
if (i>nums1.length||(k-i)>nums2.length){ //排除不可能的组合
b[i]=-1;
}
}
int []result=new int[k];
for (int i=0;i<b.length;i++){
if (b[i]==-1)
continue;
int first=b[i]; //从num1中选出的数
int second=k-b[i]; //从num2中选出的数
//分别选出最大组成数
int [] firstArr=new int[first];
int [] secondArr=new int[second];
int[] max1 = findMax(nums1, 0, first, firstArr);
int[] max2 = findMax(nums2, 0, second, secondArr);
//从 max1,max2中按顺序合并。组成组大数
int[] max = merge(max1, max2, k);
//比较所有组合
compareArr(result,max);
}
return result;
}
public static int[] merge(int []max1,int max2,int k){
int []max=new int[k];
int m=0;
int n=0;
int index=0;
while (m<max1.length&&n<max2.length){
if (max1[m]>max2[n]){
max[index]=max1[m];
m++;
}else {
if (max1[m]==max2[n]){
int o=m+1;
int p=n+1;
int flag=0;
while (o<max1.length&&p<max2.length){
if (max1[o]>max2[p])
break;
if (max1[o]<max2[p]){
flag=1;
break;}
if (max1[o]==max2[p]){
o++;
p++;
}
}
if (o>=max1.length&&p<max2.length){
flag=1;
}
if (flag==1){
max[index]=max2[n];
n++;
}else{max[index]=max1[m];
m++;
}
}else{
max[index]=max2[n];
n++;
}
}
index++;
}
while (m<max1.length){
max[index]=max1[m];
index++;
m++;
}
while (n<max2.length){
max[index]=max2[n];
index++;
n++;
}
return max;
}
public static void compareArr(int []max,int []temp){
for (int i=0;i<max.length;i++){
if (max[i]<temp[i]){
max[i]=temp[i];
for (int j=i+1;j<max.length;j++){
max[j]=temp[j];}
}
else
if (max[i]==temp[i]){
}else
break;
}
}
public static int []findMax(int []num,int start,int k,int []result){
if (k==0)
return result;
int [] result1=result;
int max=-1;
int maxIndex=0;
for (int i=start;i<num.length-k+1;i++){
if (num[i]>max){
max=num[i];
maxIndex=i;
}
}
result1[result1.length-k]=max;
findMax(num,maxIndex+1,k-1,result1);
return result1;
}