- Divida o número máximo - enumere todos os grupos - pilha monotônica + algoritmo ganancioso
Dadas duas matrizes de comprimento m e n respectivamente, seus elementos são compostos de 0 a 9, representando os números em cada bit dos dois números naturais. Agora selecione k (k <= m + n) números dessas duas matrizes e divida-os em um novo número. Os números retirados da mesma matriz são necessários para manter sua ordem relativa na matriz original.
Encontre o número máximo que satisfaz esta condição. O resultado é uma matriz de comprimento k representando o número máximo.
Nota: Otimize a complexidade de tempo e espaço do seu algoritmo tanto quanto possível.
Exemplo 1:
Entrada:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
Saída:
[9, 8, 6, 5, 3]
Exemplo 2:
Entrada:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
Saída:
[6, 7, 6, 0, 4]
Exemplo 3:
Entrada:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
Saída:
[9, 8, 9]
Para esta questão, qual é o ponto chave? Por exemplo, se quisermos combinar para obter o maior número, então sabemos como combiná-lo a partir das duas matrizes fornecidas. Suponha que a primeira matriz tenha oito números e a segunda tenha oito
números
. Matriz de nove números.
Agora pegue três números do primeiro e três números do segundo. Os três números obtidos devem ser o maior número de três dígitos. Isso se deve principalmente a esta inferência.
Depois de conhecermos essa inferência, nosso objetivo passa a ser retirar todas as combinações, depois dividir o número máximo dessas combinações e, em seguida, encontrar a maior dentre esses números máximos. O código de resolução de problemas é o seguinte:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
void monotone_stack(int *nums,int count,int *s,int numsSize){
int top=0;
for(int i=0;i<numsSize;i++){
// printf("top %d ",top);
if(i==0){
s[top++]=nums[i];
}
else{
if(top>=1)
while(top>=1&&nums[i]>s[top-1]&&numsSize-i>=count-top+1){
top--;
}
if(top<count){
s[top++]=nums[i];
}
}
}
}
void print(int *nums,int numsSize){
for(int i=0;i<numsSize;i++){
printf("%d ",nums[i]);
}
}
void find_max(int *ret,int k,int *s1,int *s2,int n1,int n2){
int p1=0,p2=0;
int i=0;
for(;i<k;){
if(p1==n1||p2==n2){
break;
}
else{
if(s1[p1]>s2[p2]){
ret[i]=s1[p1];
p1++;
i++;
}
else if(s1[p1]<s2[p2]){
ret[i]=s2[p2];
p2++;
i++;
}
else if(s1[p1]==s2[p2]){
// ret[i]=s1[p1];
// p1++;
int po1=p1;
int po2=p2;
while(s1[po1]==s2[po2]){
po1++;
po2++;
if(po1==n1){
break;
}
if(po2==n2){
break;
}
}
if(po1==n1){
ret[i]=s2[p2];
p2++;
i++;
}
else if(po2==n2){
ret[i]=s1[p1];
p1++;
i++;
}
else{
if(s1[po1]>s2[po2]){
ret[i]=s1[p1];
p1++;
i++;
// printf(" %d i %d ",ret[i],i);
}
if(s1[po1]<s2[po2]){
ret[i]=s2[p2];
p2++;
i++;
}
}
}
}
}
while(p1!=n1){
ret[i++]=s1[p1++];
}
while(p2!=n2){
ret[i++]=s2[p2++];
}
for(int i=0;i<k;i++){
printf("-%d ",ret[i]);
}
}
int* maxNumber(int* nums1, int nums1Size, int* nums2, int nums2Size, int k, int* returnSize){
int *s1=(int *)malloc(sizeof(int)*nums1Size);
int *s2=(int *)malloc(sizeof(int)*nums2Size);
int *re=(int *)malloc(sizeof(int)*k);
int *ret=(int *)malloc(sizeof(int)*k);
*returnSize=k;
int pz=0;
for(int i=1;i<=nums1Size&&i<=k;i++){
if(nums2Size>=k-i){
monotone_stack(nums1,i,s1,nums1Size);
monotone_stack(nums2,k-i,s2,nums2Size);
printf("||");
// print(s1,i);
// print(s2,k-i);
if(pz==0){
find_max(re,k,s1,s2, i, k-i);
pz=1;
}
else{
find_max(ret,k,s1,s2, i, k-i);
for(int j=0;j<k;j++){
if(ret[j]>re[j]){
for(int kz=0;kz<k;kz++){
re[kz]=ret[kz];
}
break;
}
if(ret[j]<re[j]){
break;
}
}
}
}
}
return re;
}