Mesclar duas listas classificadas


14

Mesclar Classificação

Nesse desafio, você implementará a sub-rotina de mesclagem da classificação de mesclagem. Especificamente, você deve criar uma função ou programa ou verbo ou similar que utilize duas listas, cada uma classificada em ordem crescente, e as combine em uma lista classificada em ordem crescente. Requisitos:

- Seu algoritmo deve levar uma quantidade de tempo assintoticamente linear no tamanho da entrada. Pare de fornecer soluções O (n ^ 2).

  • Você não pode usar nenhuma função interna capaz de classificar uma lista, mesclar uma lista ou algo assim. Discrição do autor.
  • O código deve ser capaz de lidar com elementos repetidos.
  • Não se preocupe com listas vazias.

Exemplos:

merge([1],[0,2,3,4])
[0,1,2,3,4]

merge([1,5,10,17,19],[2,5,9,11,13,20])
[1, 2, 5, 5, 9, 10, 11, 13, 17, 19, 20]

Isso é , então o código mais curto pode ganhar!


Temos que lidar com elementos repetidos em uma lista ou apenas entre as duas listas?
perfil completo de Keith Randall

Digamos os dois. A ideia é que você possa usar isso para fazer a classificação por mesclagem.
Isaacg

É melhor eliminar as matrizes de entrada?
amigos estão dizendo sobre skibrianski

3
Não sei como interpretar algoritmos deve levar uma quantidade de tempo assintoticamente linear . Algoritmos não demoram, implementações. O tempo de execução da minha resposta Golfscript é O (assustador) com o intérprete Ruby, mas o Online Golfscript Tester se comporta muito melhor e pode ser de fato linear (sem nenhuma maneira real de saber sem o código-fonte). O que quero dizer é: b=a;b=b.lengthpode duplicar toda a matriz a(e resultar em tempo O (n ^ 2) se executado para cada elemento) ou duplicar apenas a referência à matriz (tempo O (n)). Qual conta?
9114 Dennis

1
Eu acho que em casos como esses, faça o possível para descobrir, mas se você honestamente não souber, pode assumir que as coisas funcionam bem, como a segunda alternativa que você mencionou. Você pode supor que o intérprete funcione bem se o seu idioma não tiver um intérprete padrão.
Isaacg

Respostas:


8

Rebmu ( 35 32 caracteres)

u[iG^aNXa[rvA]apGtkFaM?fA]apGscA

Teste

>> rebmu/args [u[iG^aNXa[rvA]apGtkFaM?fA]apGscA] [[1 5 10 17 19] [2 5 9 11 13 20]] 
== [1 2 5 5 9 10 11 13 17 19 20]

>> rebmu/args [u[iG^aNXa[rvA]apGtkFaM?fA]apGscA] [[2 5 9 11 13 20] [1 5 10 17 19]] 
== [1 2 5 5 9 10 11 13 17 19 20]

Sobre

Rebmu é um dialeto de Rebol que permite 'mesclar' o código regular para situações que exigem brevidade. Sem silêncio, o código funciona da seguinte forma:

u [                     ; until
    i g^ a nx a [       ; if greater? args next args
       rv a             ; reverse args
    ]                   ; (we want the block containing the next value first)

    ap g tk f a         ; append output take first args
    m? f a              ; empty? first args
]                       ; (first block is now empty)

ap g sc a               ; append output second args
                        ; (add the remainder of the second)

Acredito que isso satisfaça o requisito de O (n) , pois o bloco till é repetidamente repetido tantas vezes quanto o comprimento da entrada (e o reverseúnico alterna a ordem do contêiner dos blocos de entrada, não os próprios blocos). O uso takeé talvez uma liberdade, mas ainda é um pequeno golpe de eficiência.

Rebol ( 83 75 caracteres)

Um pouco diferente: no Rebol, os caminhos são uma expressão mais curta que firstou second. aé o bloco de entrada que contém os dois blocos:

until[if a/2/1 < a/1/1[reverse a]append o:[]take a/1 tail? a/1]append o a/2

5

Soluções da OP:

Haskell 49 44 40

k@(p:r)%l@(q:s)|p>=q=q:k%s|0<1=l%k
a%_=a

Python 131 105 101 99 93

Com agradecimentos a @Evpok:

f=lambda u,v:v and(v[-1]<u[-1]and f(v,u)or[b.append(a)for a,b in[(v.pop(),f(u,v))]]and b)or u

1
Você pode escrever a%b=a++bapós a correspondência principal de padrões para lidar com listas vazias, que eliminarão alguns caracteres.
swish

a solução Haskell não falha se a primeira lista ficar sem conteúdo primeiro?
John Dvorak

Se você observar a primeira função, ela chamará recursivamente a função com a lista encurtada como o segundo argumento e a lista alongada como o primeiro argumento, ou então troque os argumentos. Portanto, o primeiro argumento nunca fica mais curto. Como, pelo OP, ele não começa vazio, nunca será vazio.
Isaacg

4

Python (79)

from itertools import*
def m(*a):
 while any(a):yield min(compress(a,a)).pop(0)

Python (95, se não tivermos permissão para retornar um gerador)

from itertools import*
def m(*a):
 r=[]
 while any(a):r+=[min(compress(a,a)).pop(0)]
 return r

Itertools é a solução para todos os problemas mundanos.

Bônus: os dois trabalham em um número arbitrário de listas e se preocupam com listas vazias (como, eles pegam 2 listas vazias e retornam uma lista vazia ou levam 1 lista vazia e 1 não vazia, e eles retornarão o item não vazio. Outro recurso adicional dos 2 itens não produzidos: eles também serão executados sem argumentos e retornarão uma lista vazia.)

Ungolfed:

from itertools import *  # Import all items from itertools
def m(*a):               # Define the function m, that takes any number of arguments, 
                         #  and stores those arguments in list a
    r=[]                 # Create an empty list r                         
    while any(a):        # While any element in a returns True as value:
        b=compress(a,a)  # Remove any element from a that isn't True (empty lists)
                         #  The example in the official documentation is this one:
                         #  compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
        c=min(b)         # Sort the lists by first value, and take the first one of these.
        d=c.pop(0)       # Take the first element from c
        r.append(d)      # Append this first element to r
    return r             # Gives back r

Em suas soluções sem gerador, use r+=[...]em vez de r.append(...)(poupa 4 caracteres de cada vez)
HLT

Não me refiro a nenhuma ofensa por isso, mas se sua resposta contiver código em um idioma que é apenas outro idioma com modificações feitas especificamente para o golfe, eu vou rebaixá-lo. É uma pena, as respostas reais em python são boas.
Undergroundmonorail

Se você os dividir em postagens diferentes, eu votarei mais no python.
undergroundmonorail

4
@undergroundmonorail Você rebaixou todas as respostas do GolfScript?
Evpok

1
@ Evpok Agora que você mencionou, é melhor jogar no meta e ver o que eles têm a dizer lá.
ɐɔıʇǝɥʇuʎs

3

C - 75

Isso opera em NULLmatrizes terminadas de int *, embora funcione igualmente bem para ponteiros para outros tipos, substituindo a função de comparação apropriada por **b < **a(por exemplo, strcmp(*b, *a) < 0).

void m(int**a,int**b,int**c){while(*a||*b)*c++=!*a||*b&&**b<**a?*b++:*a++;}

Ungolfed:

void merge(int **a, int **b, int **c)
{
    while(*a || *b)
        *c++ = !*a || *b && **b < **a
            ? *b++
            : *a++;
}

3

Golfscript, 29 27 30 29 26 bytes

~{.0=@.0=@<{}{\}if(@@.}do;~]p

ou

~{.0=@.0=@>{\}*(@@.}do;~]p

Como funciona

O comando

golfscript merge.gs <<< '[2 3] [1 4]'

será processado da seguinte maneira:

~            # Interpret the input string.
             #
             # STACK: [2 3] [1 4]
{            #
    .@=0.@=0 # Duplicate the two topmost arrays of the stack and extract their first 
             # elements. This reverses the original order of the first copy.
             #
             # STACK: [1 4] [2 3] 2 1
             #
    >        # Check if the respective first elements of the arrays are ordered.
             #
             # STACK: [1 4] [2 3] 1
             #
    {\}*     # If they are not, swap the arrays. This brings the array with the smallest
             # element to the top of the stack.
             #
             # STACK: [2 3] [1 4]
             #
    (@@      # Shift the first element of the array on top of the stack and rotate it
             # behind the arrays.
             #
             # STACK: 1 [2 3] [4]
             #
    .        # Duplicate the topmost array.
             #
             # STACK: 1 [2 3] [4] [4]
             #
}do          # Repeat this process if the array is non-empty.
             #
             # STACK: 1 [2 3] [4] -> 1 2 [4] [3] -> 1 2 3 [4] []
             #
;~           # Delete the empty array from the stack and dump the non-empty array.
             #
             # STACK: 1 2 3 4
             #
]p           # Combine all elements on the stack into a single array, the to a string and
             # print.

A saída é:

[1 2 3 4]

A duplicação de matrizes na pilha torna O (n ^ 2)?
swish

@swish: Não sou cientista da computação, mas eu diria que depende da implementação. Se o intérprete realmente duplicar as matrizes inteiras, acho que sim.
Dennis

A versão anterior era O (n ^ 2) para matrizes muito semelhantes (por exemplo, [1 1 1 ... 2]e [1 1 1 ... 3]), pois a comparação das matrizes (em vez de seus primeiros elementos) seria muito lenta nesse caso.
911 Dennis

As únicas operações de matriz que ocorrem na nova versão são duplicação, troca e rotação na pilha. Como as matrizes duplicadas são usadas apenas para extrair elementos únicos e testar a falta de vazio das matrizes (ambas operações destrutivas no Golfscript), o código acima pode ser executado em O (n) tempo (duplicando, trocando e girando as referências para o matrizes). O desempenho real depende do intérprete.
911 Dennis

2

J - 42. 33

Versão modificada daqui + o comentário de @algorithmshark

k=:(m}.),~0{]
m=:k~`k@.(>&{.) ::,

kprecede o cabeçalho da matriz direita às caudas mescladas de ambas as matrizes. k~é o mesmo, mas com matrizes invertidas. (>&{.)está comparando as cabeças. O código emitirá um erro se uma das matrizes estiver vazia; nesse caso, retornamos apenas sua concatenação ,.


Estou presumindo que, uma vez que /:~ a,bé a resposta proibida (junto com [:/:~,), você está procurando a resposta mais curta que não inclua/: , certo?
Dane

Vou salientar que a pergunta afirma: "Não se preocupe com listas vazias".
Dane

@Dane O teste de vazio necessário para a recursão parar.
swish

m=:k~`k@.(>&{.)`,@.(0=*&#)economiza 2 caracteres.
algoritmshark

Na verdade, você pode reduzir tudo para 33 caracteres: k=:(m}.),~0{] e m=:k~`k@.(>&{.) ::,. Usamos 0{para lançar um erro quando a lista está vazia e, em seguida, capturar esse erro e sair com ,.
algorithmshark

2

JavaScript (ES6), 69 79 bytes

f=(a,b,c=[])=>(x=a[0]<b[0]?a:b).length?f(a,b,c.concat(x.shift())):c.concat(a,b)

Como funciona

f = (a, b, c = []) =>          // `f' is a function that takes arguments `a', `b' and `c' -
                               // `c' defaults to `[]' - which returns the following
                               // expression:
                               //
 (x = a[0] < b[0] ? a : b)     // Store the array among `a' and `b' with the smaller first 
                               // element in `x'.
                               //
 .length ?                     // If it's non-empty,
                               //
  f(a, b, c.concat(x.shift())) // append the first element of array `x' to array `c' and run
                               // `f' again;
                               //
  : c.concat(a,b)              // otherwise, append the arrays `a' and `b' to `c'.
                               //
)

Comparar as matrizes com o <operador não é válido, pois faz uma comparação de cadeias:f([123, 456, 789], [1, 2, 3, 4, 5]) => [1, 123, 2, 3, 4, 456, 5, 789]
nderscore

@nderscore: Certo. De qualquer maneira, não teria funcionado, pois a comparação de todas as matrizes pode não ser O (n). O mesmo parece ser verdade para o teste de não-vazio, que precisa converter toda a matriz em uma string.
Dennis

Sim, não tenho certeza de qual é o grande problema da conversão de tipo de matriz-> string.
Nscorecore 9/04

1
Concatenar uma matriz []e convertê-la em uma seqüência de caracteres requer tempo O (n). Fazer isso uma vez para todos os n elementos da matriz leva tempo O (n ^ 2).
911 Dennis

Faz sentido. Entendi.
Nscorecore 9/04

2

Python (63) (69) (71)

def m(a,b):
 if a[0]>b[0]:a,b=b,a
 return[a.pop(0)]+(m(a,b)if a else b)

Eu escrevi isso antes de ver os comentários do OP sobre tempos de execução de outras respostas, então essa é outra solução que é O (n) no algoritmo, mas não na implementação.


Quais algoritmos têm extrações da frente das matrizes como O (1)? Quais algoritmos possuem comparações de lista O (1)? Além disso, você pode golfe que mais mudando ... if ... else ... para ... e ... ou ...
isaacg

@isaacg Shoot, eu tinha esquecido repetições, possivelmente fazendo a comparação da lista O (n). Então, retirei essa otimização para mais 6 caracteres. Você pode extrair e anexar à frente em O (1) em uma lista vinculada. Não vejo como você pode fazer ... e ... ou ... se comportar bem ao retornar o valor.
Xnor

OK, agora vejo como fazer ... e ... ou ..., mas não salva os caracteres devido às parênteses necessárias. return[a.pop(0)]+(a and m(a,b)or b)
Xnor

@isaacg: Para extrair a frente de uma matriz em O (1), basta aumentar o ponteiro da matriz de modo que aponte para o segundo elemento e libere a memória consumida pelo primeiro elemento.
Wrzlprmft

@Wrzlprmft Não consegui fazer o truque da matriz funcionar porque os dois elementos da matriz são avaliados independentemente do valor booleano, que gera um erro quando a é a lista vazia. Existe uma maneira curta de criar uma "matriz lenta"?
Xnor

2

Haskell, 35 bytes

a#b@(c:d)|a<[c]=b#a|0<1=c:a#d
a#_=a

Haskell, 30 bytes (não concorrente)

Esta versão não concorrente garante apenas tempo de execução linear se ae btiver elementos disjuntos; caso contrário, ainda funcionará corretamente, mas poderá usar o tempo quadrático.

a#b|a<b=b#a|c:d<-b=c:a#d
a#_=a

2

PHP 91 98 91 bytes

editar # 1: Vazio $brequer uma condição adicional nos chavetas (+7).
edit # 2: golfe menor
edit # 3: segunda versão adicionada

bem direto. A parte mais legal é o ternário dentro do array_shift
(que falha se você tentar sem os curlys)

function m($a,$b){for($c=[];$a|$b;)$c[]=array_shift(${$a&(!$b|$a[0]<$b[0])?a:b});return$c;}

ou

function m($a,$b){for($c=[];$a|$b;)$c[]=array_shift(${$a?!$b|$a[0]<$b[0]?a:b:b});return$c;}

destroçado

function m($a,$b)
{
    $c=[];
    while($a||$b)
    {
        $c[] = array_shift(${
            $a&&(!$b||$a[0]<$b[0])
                ?a
                :b
        });
#       echo '<br>', outA($a), ' / ', outA($b) , ' -> ', outA($c);
    }
    return $c;
}

teste

$cases = array (
    [1],[0,2,3,4], [0,1,2,3,4],
    [1,5,10,17,19],[2,5,9,11,13,20], [1, 2, 5, 5, 9, 10, 11, 13, 17, 19, 20],
    [1,2,3],[], [1,2,3],
    [],[4,5,6], [4,5,6],
);
function outA($a) { return '['. implode(',',$a). ']'; }
echo '<table border=1><tr><th>A</th><th>B</th><th>expected</th><th>actual result</th></tr>';
while ($cases)
{
    $a = array_shift($cases);
    $b = array_shift($cases);
#   echo '<hr>', outA($a), ' / ', outA($b) , ' -> ', outA($c);
    $expect = array_shift($cases);
    $result=m($a,$b);
    echo '<tr><td>',outA($a),'</td><td>',outA($b),'</td><td>', outA($expect), '</td><td>', outA($result),'</td></tr>';
}
echo '</table>';

Eu não conseguia entender por que você não torna simples, em $a&(!$b|$a[0]<$b[0])?$a:$bvez de${$a&(!$b|$a[0]<$b[0])?a:b}
Jörg Hülsermann 11/04

1
@ JörgHülsermann O array_shiftparâmetro é usado por referência. Tem que ser uma variável; uma expressão não funciona.
Titus

1

Go, 124 caracteres

func m(a,b[]int)(r[]int){for len(a)>0{if len(b)==0||a[0]>b[0]{a,b=b,a}else{r=append(r,a[0]);a=a[1:]}};return append(r,b...)}

1

JavaScript - 133

function m(a,b){c=[];for(i=j=0;i<a.length&j<b.length;)c.push(a[i]<b[j]?a[i++]:b[j++]);return c.concat(a.slice(i)).concat(b.slice(j))}

Mesmo tipo de abordagem que os OPs.


1

perl, 87 caracteres / perl 5.14, 78 + 1 = 79 caracteres

Esta implementação reprova as referências da matriz de entrada. Fora isso, é bem direto: enquanto as duas matrizes têm algo, desative a parte inferior das duas. Em seguida, retorne o bit mesclado associado aos bits restantes (apenas um de @ $ x ou @ $ y permanecerá). Perl5 em linha reta, 87 caracteres:

sub M{($x,$y,@o)=@_;push@o,$$x[0]>$$y[0]?shift@$y:shift@$x while@$x&&@$y;@o,@$x,@$y}

Usando perl 5.14.0 e seu novo conjunto de variáveisref shift: 78 caracteres + 1 pena de caractere = 79 caracteres:

sub M{($x,$y,@o)=@_;push@o,shift($$x[0]>$$y[0]?$y:$x)while@$x&&@$y;@o,@$x,@$y}

*em vez de &&salvará um byte. E ainda mais sesub M{map{shift(!@$x+@$y*($$y[0]<$$x[0])?$y:$x)}map@$_,($x,$y)=@_}
user2846289

@VadimR, uau. bom trabalho. Vá em frente e poste isso, se quiser - eu nunca teria pensado em fazer o truque do mapa duplo em vez de pressionar uma matriz.
precisa saber é o seguinte

1

Java: 144

Isso é bem direto. Uma função que pega duas matrizes e retorna uma, a versão mesclada, golfed e sem wrapper de compilação:

int[]m(int[]a,int[]b){int A=a.length,B=b.length,i,j;int[]c=new int[A+B];for(i=j=0;i+j<A+B;c[i+j]=j==B||i<A&&a[i]<b[j]?a[i++]:b[j++]);return c;}

Ungolfed (com wrapper compilável e executável):

class M{
    public static void main(String[]args){
        int[]a=new int[args[0].split(",").length];
        int i=0;
        for(String arg:args[0].split(","))
            a[i++]=Integer.valueOf(arg);
        int[]b=new int[args[1].split(",").length];
        int j=0;
        for(String arg:args[1].split(","))
            b[j++]=Integer.valueOf(arg);
        int[]c=(new M()).m(a,b);
        for(int d:c)
            System.out.printf(" %d",d);
        System.out.println();
    }
    int[]m(int[]a,int[]b){
        int A=a.length,B=b.length,i,j;
        int[]c=new int[A+B];
        for(i=j=0;i+j<A+B;c[i+j]=j==B||i<A&&a[i]<b[j]?a[i++]:b[j++]);
        return c;
    }
}

Execuções de exemplo:

$ javac M.java
$ java M 10,11,12 0,1,2,20,30
 0 1 2 10 11 12 20 30
$ java M 10,11,12,25,26 0,1,2,20,30
 0 1 2 10 11 12 20 25 26 30

Qualquer dica para encurtar seria apreciada.


1

Scala, 97 bytes

Solução recursiva com O (n). Para encurtar o código, algumas vezes uma operação é feita alternando os 2 parâmetros intercambiáveis, ou seja, f (a, b) chama f (b, a).

type L=List[Int];def f(a:L,b:L):L=if(a==Nil)b else if(a(0)<=b(0))a(0)::f(a.drop(1),b) else f(b,a)

Ungolfed:

type L=List[Int]

def f(a:L, b:L) : L =
  if (a == Nil)
    b 
  else 
    if (a(0) <= b(0))
      a(0) :: f(a.drop(1), b) 
    else
      f(b,a)

Excepção se um é não vazio, mas b está vazia
Dan Óssipov

1

APL (32)

{⍺⍵∊⍨⊂⍬:⍺,⍵⋄g[⍋g←⊃¨⍺⍵],⊃∇/1↓¨⍺⍵}

Explicação:

{⍺⍵∊⍨⊂⍬                               if one or both of the arrays are empty
        :⍺,⍵                           then return the concatenation of the arrays
             ⋄g[⍋g←⊃¨⍺⍵]              otherwise return the sorted first elements of both arrays
                          ,⊃∇/        followed by the result of running the function with
                               1↓¨⍺⍵}  both arrays minus their first element

1

LISP, 117 bytes

O algoritmo termina em n + 1iterações, onde né o comprimento da lista mais curta da entrada.

(defun o(a b)(let((c(car a))(d(car b)))(if(null a)b(if(null b)a(if(< c d)(cons c(o(cdr a)b))(cons d(o a(cdr b))))))))


0

Python - 69 bytes

def m(A,B):
    C=[]
    while A and B:C+=[[A,B][A>B].pop(0)]
    return C+A+B

Se a ordem de entrada e saída fosse decrescente, isso poderia ser reduzido para 61 bytes :

def m(A,B):
    C=[]
    while A+B:C+=[[A,B][A<B].pop(0)]
    return C

E ainda mais até 45 bytes, se geradores forem permitidos:

def m(A,B):
    while A+B:yield[A,B][A<B].pop(0)

Definitivamente, este não é O (n). .pop (0) e + = são operações O (n) que você realiza O (n) vezes.
Isaacg

Até agora, eu nem sabia que listas não são implementadas como listas em Python e, mesmo assim, pop(0)podem ser implementadas em O (1) e +=pelo menos podem ser implementadas melhor que O (n) (veja o link). A propósito, sua solução usa +=(ou seja, appende extend) tantas vezes quanto a minha. Enfim, tudo isso é uma questão de implementação (tanto quanto eu sei); portanto, em uma implementação Python (fictícia), onde as listas são implementadas como listas, minha função é O (n). Finalmente, sua pergunta exigia que o algoritmo fosse O (n), e o meu é.
precisa saber é o seguinte

Na verdade, anexar e estender são implementados de maneira diferente em python que + = é. + = cria uma nova lista, enquanto .append e .extend modificam uma lista existente.
Isaacg

0

Perl 6: 53 caracteres

sub M(\a,\b){{shift a[0]>b[0]??b!!a}...{a^b},a[],b[]}

Desloque-se de qualquer valor que tenha o valor menor aou baté aXOR b( a^b) ser verdadeiro. Em seguida, retorne o que restar, achatando ( []) as matrizes na lista ( a[],b[]).

Supondo que a mudança desde o início de uma matriz seja O (n), o pior caso é duas comparações e uma mudança por elemento; portanto, o algoritmo é O (n).


0

JavaScript (ES5) 90 86 90 bytes

function f(a,b){for(o=[];(x=a[0]<b[0]?a:b).length;)o.push(x.shift());return o.concat(a,b)}

edit: (90 -> 86) Moveu o ternário para a condição do loop for. Idéia roubada de Dennis.

edit: (86 -> 90) Removida a matriz para a conversão de String, pois quebra o requisito de O (n) .


0

Mathematica, 137 135

m[a_,b_]:=(l=a;Do[Do[If[b[[f]]<=l[[s]],(l=Insert[l,b[[f]],s];Break[]),If[s==Length@l,l=l~Append~b[[f]]]],{s,Length@l}],{f,Length@b}];l)

Entrada:

m[{2,2,4,6,7,11},{1,2,3,3,3,3,7}]

Resultado:

{1, 2, 2, 2, 3, 3, 3, 3, 4, 6, 7, 7, 11}

Ungolfed:

mergeList[a_, b_] := (
    list = a;
    Do[
        Do[(
            If[
                b[[f]] <= list[[s]],
                (list = Insert[list, b[[f]], s]; Break[]),
                If[
                    s == Length@list,
                    list = list~Append~b[[f]]
                ]
        ]),
        {s, Length@list}
    ],
    {f, Length@b}
    ];
    list
)

Provavelmente poderia fazer melhor.


m[a:{x___,y_},b:{___,z_}]:=If[y<z,b~m~a,{x}~m~b~Join~{y}];{}~m~b_=b;
alephalpha

0

R, 80

A mesma solução que no Scala e em outros idiomas. Não tenho tanta certeza sobre x [-1] é O (1).

f=function(a,b)if(length(a)){if(a[1]<=b[1])c(a[1],f(a[-1],b))else f(b,a)}else b

0

Mathematica, 104 bytes

Reap[{m,n}=Length/@{##};i=k=1;Do[If[k>n||TrueQ[#[[i]]<#2[[k]]],Sow@#[[i++]],Sow@#2[[k++]]],n+m]][[2,1]]&

Função anônima, armazena o comprimento das duas listas de entrada nas variáveis m e n, em seguida, cada iteração do Doloop Sowé um elemento de uma das listas que incrementam o contador dessa lista ( ipara a primeira, kpara a segunda) em uma. Se um dos contadores exceder o comprimento da lista, a Ifinstrução sempre será Sowo elemento da outra lista. Após as n+moperações, todos os elementos foram resolvidos. Reapou melhor, parte [[2,1]]de sua saída é uma lista de elementos na ordem em que foram Sown.

Não tenho certeza das informações internas (está acessando uma parte de uma lista O(1)ou não), mas os tempos pareciam bastante lineares na minha máquina com relação ao tamanho da lista de entrada.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.