题目如下:
给出两个长度分别是m
和n
的数组来表示两个大整数,数组的每个元素都是数字0-9
。从这两个数组当中选出k
个数字来创建一个最大数,其中k
满足k <= m + n
。选出来的数字在创建的最大数里面的位置必须和在原数组内的相对位置一致。返回k
个数的数组。你应该尽可能的去优化算法的时间复杂度和空间复杂度。
样例
给出 nums1 = [3, 4, 6, 5]
, nums2 = [9, 1, 2, 5, 8, 3]
, k = 5
返回 [9, 8, 6, 5, 3]
选出一个最大数,并不难,但这题却需要选出的数字与原数组位置相对,这就比较特殊了。因为考虑的不但是所给数组长度问题,还是K的问题。明显,这题的主要思路就是寻找相对位置。
如下图中,可揭示数组中相对位置的规律:len-1=u(n-1)+d(n-1)
按照相对位置规律,我们可以利用d来求得另一个位置u。需要注意的是,因为我们的d源于新数组,即是由新数组的位置来确定其他数组的相对位置,因此在d>其余数组len时,d很可能需要与u发生互换,即取min(d,k-1-d),原因为d跟u是对称位置的,当d<=其余数组len时,d为本身。至于重复元素问题,把重复元素赋为0即可。这样一来,只需要遍历k遍就能完成解答。
思路代码实现如下:
#define min(a,b) a<b?a:b
void Method(int *s,int slen,int *e,int elen,int k)
{
int p=min(slen,elen),r,ts,te,u_1=0,u_2=0;
int *v=(int *)malloc(4*k),o=0;
while(o<k)
{
r=o<p?o:min(o,k-1-o);
ts=r<slen?s[r]>s[slen-1-r]?u_1=r,s[r]:(u_1=slen-1-r,s[slen-1-r]):0;
te=r<elen?e[r]>e[elen-1-r]?u_2=r,e[r]:(u_2=elen-1-r,e[elen-1-r]):0;
v[o]=ts<te?(e[u_2]=0,te):(s[u_1]=0,ts);
printf("%d ",v[o]);
o++;
}
free(v);
}