Los objetos le permiten almacenar colecciones de valores con clave. Está bien.
Pero muy a menudo encontramos que necesitamos una colección ordenada , donde tenemos un primer, un segundo, un tercer elemento, etc. Por ejemplo, lo necesitamos para almacenar una lista de algo: usuarios, productos, elementos HTML, etc.
No es conveniente utilizar un objeto aquí porque no proporciona métodos para gestionar el orden de los elementos. No podemos insertar una nueva propiedad “entre” las existentes. Los objetos simplemente no están destinados a ese uso.
Existe una estructura de datos especial llamada Array
, para almacenar colecciones ordenadas.
Hay dos sintaxis para crear una matriz vacía:
let arr = nueva matriz(); let arr = [];
Casi todo el tiempo se utiliza la segunda sintaxis. Podemos suministrar elementos iniciales entre paréntesis:
let frutas = ["Manzana", "Naranja", "Ciruela"];
Los elementos de la matriz están numerados, comenzando con cero.
Podemos obtener un elemento por su número entre corchetes:
let frutas = ["Manzana", "Naranja", "Ciruela"]; alerta( frutas[0] ); // Manzana alerta( frutas[1] ); // Naranja alerta( frutas[2] ); // Ciruela
Podemos reemplazar un elemento:
frutas[2] = 'Pera'; // ahora ["Manzana", "Naranja", "Pera"]
…O agregue uno nuevo a la matriz:
frutas[3] = 'Limón'; // ahora ["Manzana", "Naranja", "Pera", "Limón"]
El recuento total de elementos de la matriz es su length
:
let frutas = ["Manzana", "Naranja", "Ciruela"]; alerta( frutas.longitud ); // 3
También podemos usar alert
para mostrar toda la matriz.
let frutas = ["Manzana", "Naranja", "Ciruela"]; alerta( frutas ); // manzana, naranja, ciruela
Una matriz puede almacenar elementos de cualquier tipo.
Por ejemplo:
// mezcla de valores let arr = [ 'Apple', { nombre: 'John' }, verdadero, función() { alerta('hola'); } ]; //obtiene el objeto en el índice 1 y luego muestra su nombre alerta(arr[1].nombre); // John // obtenemos la función en el índice 3 y la ejecutamos arreglo[3](); // Hola
coma final
Una matriz, al igual que un objeto, puede terminar con una coma:
dejar frutas = [ "Manzana", "Naranja", "Ciruela", ];
El estilo de “coma final” facilita la inserción/eliminación de elementos, porque todas las líneas se vuelven iguales.
Una adición reciente
Esta es una adición reciente al idioma. Los navegadores antiguos pueden necesitar polyfills.
Digamos que queremos el último elemento de la matriz.
Algunos lenguajes de programación permiten el uso de índices negativos para el mismo propósito, como fruits[-1]
.
Aunque en JavaScript no funcionará. El resultado será undefined
, porque el índice entre corchetes se trata literalmente.
Podemos calcular explícitamente el índice del último elemento y luego acceder a él: fruits[fruits.length - 1]
.
let frutas = ["Manzana", "Naranja", "Ciruela"]; alerta( frutas[frutas.longitud-1] ); // Ciruela
Un poco engorroso, ¿no? Necesitamos escribir el nombre de la variable dos veces.
Afortunadamente, existe una sintaxis más corta: fruits.at(-1)
:
let frutas = ["Manzana", "Naranja", "Ciruela"]; // igual que frutas[frutas.longitud-1] alerta( frutas.at(-1) ); // Ciruela
En otras palabras, arr.at(i)
:
es exactamente lo mismo que arr[i]
, si i >= 0
.
para valores negativos de i
, retrocede desde el final de la matriz.
Una cola es uno de los usos más comunes de una matriz. En informática, esto significa una colección ordenada de elementos que admite dos operaciones:
push
agrega un elemento al final.
shift
obtiene un elemento desde el principio, avanzando la cola, de modo que el segundo elemento se convierte en el primero.
Las matrices admiten ambas operaciones.
En la práctica lo necesitamos muy a menudo. Por ejemplo, una cola de mensajes que deben mostrarse en pantalla.
Hay otro caso de uso para las matrices: la estructura de datos denominada pila.
Admite dos operaciones:
push
agrega un elemento al final.
pop
toma un elemento del final.
Así que los nuevos elementos se añaden o quitan siempre desde el “final”.
Una pila generalmente se ilustra como una baraja de cartas: se agregan cartas nuevas en la parte superior o se toman desde arriba:
Para las pilas, el último elemento enviado se recibe primero, lo que también se denomina principio LIFO (último en entrar, primero en salir). Para las colas, tenemos FIFO (primero en entrar, primero en salir).
Las matrices en JavaScript pueden funcionar tanto como cola como pila. Te permiten agregar/eliminar elementos, tanto al principio como al final.
En informática, la estructura de datos que permite esto se llama deque.
Métodos que funcionan con el final de la matriz:
pop
Extrae el último elemento de la matriz y lo devuelve:
let frutas = ["Manzana", "Naranja", "Pera"]; alerta( frutas.pop() ); // eliminar "Pera" y alertarlo alerta( frutas ); // manzana, naranja
Tanto fruits.pop()
como fruits.at(-1)
devuelven el último elemento de la matriz, pero fruits.pop()
también modifica la matriz eliminándola.
push
Agregue el elemento al final de la matriz:
let frutas = ["Manzana", "Naranja"]; frutas.push("Pera"); alerta( frutas ); // Manzana, Naranja, Pera
La llamada fruits.push(...)
es igual a fruits[fruits.length] = ...
.
Métodos que funcionan con el comienzo de la matriz:
shift
Extrae el primer elemento de la matriz y lo devuelve:
let frutas = ["Manzana", "Naranja", "Pera"]; alerta( frutas.shift() ); // eliminar Apple y alertarlo alerta( frutas ); // Naranja, Pera
unshift
Agregue el elemento al comienzo de la matriz:
let frutas = ["Naranja", "Pera"]; frutas.unshift('Apple'); alerta( frutas ); // Manzana, Naranja, Pera
Los métodos push
y unshift
pueden agregar varios elementos a la vez:
let frutas = ["Manzana"]; frutas.push("Naranja", "Melocotón"); frutas.unshift("Piña", "Limón"); // ["Piña", "Limón", "Manzana", "Naranja", "Melocotón"] alerta( frutas );
Una matriz es un tipo especial de objeto. Los corchetes utilizados para acceder a una propiedad arr[0]
en realidad provienen de la sintaxis del objeto. Eso es esencialmente lo mismo que obj[key]
, donde arr
es el objeto, mientras que los números se usan como claves.
Extienden objetos proporcionando métodos especiales para trabajar con colecciones ordenadas de datos y también la propiedad length
. Pero en el fondo sigue siendo un objeto.
Recuerde, sólo hay ocho tipos de datos básicos en JavaScript (consulte el capítulo Tipos de datos para obtener más información). Array es un objeto y, por tanto, se comporta como un objeto.
Por ejemplo, se copia por referencia:
deja frutas = ["plátano"] let arr = frutas; // copiar por referencia (dos variables hacen referencia a la misma matriz) alerta( arr === frutas ); // verdadero arr.push("Pera"); // modifica la matriz por referencia alerta( frutas ); // Plátano, Pera - 2 artículos ahora
…Pero lo que hace que los arreglos sean realmente especiales es su representación interna. El motor intenta almacenar sus elementos en el área de memoria contigua, uno tras otro, tal como se muestra en las ilustraciones de este capítulo, y también hay otras optimizaciones para hacer que los arreglos funcionen realmente rápido.
Pero todos se rompen si dejamos de trabajar con una matriz como si fuera una “colección ordenada” y comenzamos a trabajar con ella como si fuera un objeto normal.
Por ejemplo, técnicamente podemos hacer esto:
dejar frutas = []; // hacer una matriz frutas[99999] = 5; // asigna una propiedad con un índice mucho mayor que su longitud frutas.edad = 25; // crea una propiedad con un nombre arbitrario
Eso es posible porque las matrices son objetos en su base. Podemos agregarles cualquier propiedad.
Pero el motor verá que estamos trabajando con la matriz como con un objeto normal. Las optimizaciones específicas de la matriz no son adecuadas para estos casos y, si se desactivan, sus ventajas desaparecen.
Las formas de hacer mal uso de una matriz:
Agregue una propiedad no numérica como arr.test = 5
.
Haga agujeros, como: agregue arr[0]
y luego arr[1000]
(y nada entre ellos).
Complete la matriz en orden inverso, como arr[1000]
, arr[999]
y así sucesivamente.
Piense en las matrices como estructuras especiales para trabajar con los datos ordenados . Proporcionan métodos especiales para eso. Las matrices se ajustan cuidadosamente dentro de los motores JavaScript para funcionar con datos ordenados contiguos; utilícelas de esta manera. Y si necesita claves arbitrarias, es muy probable que en realidad necesite un objeto normal {}
.
Los métodos push/pop
funcionan rápido, mientras que shift/unshift
son lentos.
¿Por qué es más rápido trabajar con el final de un array que con su principio? Veamos qué sucede durante la ejecución:
frutas.shift(); // toma 1 elemento desde el principio
No basta con tomar y eliminar el elemento con el índice 0
. También es necesario volver a numerar otros elementos.
La operación shift
debe hacer 3 cosas:
Elimina el elemento con el índice 0
.
Mueva todos los elementos hacia la izquierda, renumérelos del índice 1
a 0
, de 2
a 1
y así sucesivamente.
Actualice la propiedad length
.
Cuantos más elementos haya en la matriz, más tiempo habrá para moverlos y más operaciones en memoria.
Lo mismo sucede con unshift
: para agregar un elemento al comienzo de la matriz, primero debemos mover los elementos existentes hacia la derecha, aumentando sus índices.
¿Y qué pasa con push/pop
? No necesitan mover nada. Para extraer un elemento del final, el método pop
limpia el índice y acorta length
.
Las acciones para la operación pop
:
frutas.pop(); // toma 1 elemento del final
El método pop
no necesita mover nada, porque otros elementos mantienen sus índices. Por eso es increíblemente rápido.
Lo mismo ocurre con el método push
.
Una de las formas más antiguas de realizar ciclos de elementos de una matriz es el bucle for
sobre índices:
let arr = ["Manzana", "Naranja", "Pera"]; for (sea i = 0; i < arr.length; i++) { alerta( llegada[i] ); }
Pero para las matrices existe otra forma de bucle, for..of
:
let frutas = ["Manzana", "Naranja", "Ciruela"]; // itera sobre elementos de la matriz para (dejar fruto de frutas) { alerta( fruta ); }
El for..of
no da acceso al número del elemento actual, solo a su valor, pero en la mayoría de los casos es suficiente. Y es más corto.
Técnicamente, debido a que las matrices son objetos, también es posible usar for..in
:
let arr = ["Manzana", "Naranja", "Pera"]; for (deje que ingrese arr) { alerta(arr[clave]); // Manzana, Naranja, Pera }
Pero en realidad esa es una mala idea. Hay problemas potenciales con esto:
El bucle for..in
itera sobre todas las propiedades , no solo las numéricas.
En el navegador y en otros entornos existen los llamados objetos “parecidos a matrices”, que parecen matrices . Es decir, tienen propiedades length
e índices, pero también pueden tener otras propiedades y métodos no numéricos, que normalmente no necesitamos. Sin embargo, el bucle for..in
los enumerará. Entonces, si necesitamos trabajar con objetos tipo matriz, entonces estas propiedades "adicionales" pueden convertirse en un problema.
El bucle for..in
está optimizado para objetos genéricos, no para matrices, y por lo tanto es entre 10 y 100 veces más lento. Por supuesto, sigue siendo muy rápido. Es posible que la aceleración sólo importe en los cuellos de botella. Pero aun así debemos ser conscientes de la diferencia.
Generalmente, no deberíamos usar for..in
para matrices.
La propiedad length
se actualiza automáticamente cuando modificamos la matriz. Para ser precisos, en realidad no es el recuento de valores en la matriz, sino el mayor índice numérico más uno.
Por ejemplo, un único elemento con un índice grande da una longitud grande:
dejar frutas = []; frutas[123] = "Manzana"; alerta( frutas.longitud ); // 124
Tenga en cuenta que normalmente no utilizamos matrices como esa.
Otra cosa interesante acerca de la propiedad length
es que se puede escribir.
Si lo aumentamos manualmente no pasa nada interesante. Pero si lo reducimos, la matriz se trunca. El proceso es irreversible, aquí está el ejemplo:
sea arr = [1, 2, 3, 4, 5]; longitud de arreglo = 2; // truncar a 2 elementos alerta( llegada ); // [1, 2] longitud de arreglo = 5; // devolver longitud atrás alerta( arreglo[3] ); // indefinido: los valores no regresan
Entonces, la forma más sencilla de borrar la matriz es: arr.length = 0;
.
Hay una sintaxis más para crear una matriz:
let arr = new Array("Apple", "Pera", "etc");
Rara vez se usa porque los corchetes []
son más cortos. Además, tiene una característica complicada.
Si se llama a new Array
con un solo argumento que es un número, entonces crea una matriz sin elementos, pero con la longitud dada .
Veamos cómo uno puede pegarse un tiro en el pie:
let arr = nueva matriz(2); // ¿creará una matriz de [2]? alerta (arr[0]); // ¡indefinido! sin elementos. alerta (arr.longitud); // longitud 2
Para evitar este tipo de sorpresas, solemos utilizar corchetes, a menos que sepamos realmente lo que estamos haciendo.
Las matrices pueden tener elementos que también sean matrices. Podemos usarlo para matrices multidimensionales, por ejemplo para almacenar matrices:
sea matriz = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]; alerta (matriz [0] [1]); // 2, el segundo valor de la primera matriz interna
Las matrices tienen su propia implementación del método toString
que devuelve una lista de elementos separados por comas.
Por ejemplo:
sea arr = [1, 2, 3]; alerta( llegada ); // 1,2,3 alerta (Cadena (arr) === '1,2,3'); // verdadero
Además, probemos esto:
alerta( [] + 1 ); // "1" alerta( [1] + 1 ); // "11" alerta( [1,2] + 1 ); // "1,21"
Las matrices no tienen Symbol.toPrimitive
, ni un valueOf
viable, solo implementan la conversión toString
, por lo que aquí []
se convierte en una cadena vacía, [1]
se convierte en "1"
y [1,2]
se convierte en "1,2"
.
Cuando el operador binario más "+"
agrega algo a una cadena, también la convierte en una cadena, por lo que el siguiente paso se ve así:
alerta( "" + 1 ); // "1" alerta( "1" + 1 ); // "11" alerta( "1,2" + 1 ); // "1,21"
Las matrices en JavaScript, a diferencia de otros lenguajes de programación, no deben compararse con operator ==
.
Este operador no tiene un tratamiento especial para los arrays, trabaja con ellos como con cualquier objeto.
Recordemos las reglas:
Dos objetos son iguales ==
sólo si son referencias al mismo objeto.
Si uno de los argumentos de ==
es un objeto y el otro es un primitivo, entonces el objeto se convierte en primitivo, como se explica en el capítulo Conversión de objeto a primitivo.
…Con la excepción de null
e undefined
que son iguales ==
entre sí y nada más.
La comparación estricta ===
es aún más simple, ya que no convierte tipos.
Entonces, si comparamos matrices con ==
, nunca son iguales, a menos que comparemos dos variables que hacen referencia exactamente a la misma matriz.
Por ejemplo:
alerta( [] == [] ); // FALSO alerta( [0] == [0] ); // FALSO
Estas matrices son objetos técnicamente diferentes. Entonces no son iguales. El operador ==
no realiza comparaciones elemento por elemento.
La comparación con primitivas también puede dar resultados aparentemente extraños:
alerta (0 == []); // verdadero alerta('0' == []); // FALSO
Aquí, en ambos casos, comparamos una primitiva con un objeto de matriz. Entonces, la matriz []
se convierte a primitiva con fines de comparación y se convierte en una cadena vacía ''
.
Luego continúa el proceso de comparación con las primitivas, como se describe en el capítulo Conversiones de tipos:
// después de que [] se convirtiera a '' alerta( 0 == '' ); // verdadero, ya que '' se convierte al número 0 alerta('0' == '' ); // falso, sin conversión de tipos, cadenas diferentes
Entonces, ¿cómo comparar matrices?
Eso es simple: no use el operador ==
. En su lugar, compárelos elemento por elemento en un bucle o utilizando los métodos de iteración que se explican en el siguiente capítulo.
Una matriz es un tipo especial de objeto, adecuado para almacenar y gestionar elementos de datos ordenados.
La declaración:
// corchetes (habitual) let arr = [elemento1, elemento2...]; // nueva matriz (excepcionalmente rara) let arr = new Array(elemento1, elemento2...);
La llamada a new Array(number)
crea una matriz con la longitud dada, pero sin elementos.
La propiedad length
es la longitud de la matriz o, para ser precisos, su último índice numérico más uno. Se ajusta automáticamente mediante métodos de matriz.
Si acortamos length
manualmente, la matriz se trunca.
Obteniendo los elementos:
podemos obtener el elemento por su índice, como arr[0]
También podemos usar el método at(i)
que permite índices negativos. Para valores negativos de i
, retrocede desde el final de la matriz. Si i >= 0
, funciona igual que arr[i]
.
Podemos usar una matriz como deque con las siguientes operaciones:
push(...items)
agrega items
al final.
pop()
elimina el elemento del final y lo devuelve.
shift()
elimina el elemento desde el principio y lo devuelve.
unshift(...items)
agrega items
al principio.
Para recorrer los elementos de la matriz:
for (let i=0; i<arr.length; i++)
: funciona más rápido y es compatible con navegadores antiguos.
for (let item of arr)
: la sintaxis moderna solo para elementos,
for (let i in arr)
– nunca usar.
Para comparar matrices, no utilice el operador ==
(así como >
, <
y otros), ya que no tienen un tratamiento especial para las matrices. Los manejan como cualquier objeto, y no es lo que normalmente queremos.
En su lugar, puede utilizar el bucle for..of
para comparar matrices elemento por elemento.
Continuaremos con las matrices y estudiaremos más métodos para agregar, eliminar, extraer elementos y ordenar matrices en el próximo capítulo Métodos de matriz.
importancia: 3
¿Qué va a mostrar este código?
let frutas = ["Manzanas", "Pera", "Naranja"]; // inserta un nuevo valor en la "copia" let carrito de compras = frutas; carritodecompras.push("Banana"); // ¿Qué hay en las frutas? alerta( frutas.longitud ); // ?
El resultado es 4
:
let frutas = ["Manzanas", "Pera", "Naranja"]; let carrito de compras = frutas; carritodecompras.push("Banana"); alerta( frutas.longitud ); // 4
Eso es porque las matrices son objetos. Entonces, tanto shoppingCart
como fruits
son referencias a la misma matriz.
importancia: 5
Probemos 5 operaciones con matrices.
Crea una matriz de styles
con los elementos "Jazz" y "Blues".
Agregue "Rock-n-Roll" al final.
Reemplace el valor en el medio con "Clásicos". Su código para encontrar el valor medio debería funcionar para cualquier matriz con longitud impar.
Quite el primer valor de la matriz y muéstrelo.
Anteponga Rap
y Reggae
a la matriz.
La matriz en el proceso:
jazz, blues Jazz, blues, rock and roll Jazz, Clásicos, Rock-n-Roll Clásicos, Rock and Roll Rap, Reggae, Clásicos, Rock-n-Roll
let estilos = ["Jazz", "Blues"]; estilos.push("Rock-n-Roll"); estilos[Math.floor((styles.length - 1) / 2)] = "Clásicos"; alerta( estilos.shift() ); estilos.unshift("Rap", "Reggae");
importancia: 5
¿Cuál es el resultado? ¿Por qué?
let arr = ["a", "b"]; arr.push(función() { alerta (esto); }); arreglo[2](); // ?
La llamada arr[2]()
es sintácticamente el viejo obj[method]()
, en el rol de obj
tenemos arr
, y en el rol de method
tenemos 2
.
Entonces tenemos una llamada a la función arr[2]
como método de objeto. Naturalmente, recibe this
haciendo referencia al objeto arr
y genera la matriz:
let arr = ["a", "b"]; arr.push(función() { alerta (esto); }) arreglo[2](); // a,b,función(){...}
El array tiene 3 valores: inicialmente tenía dos, más la función.
importancia: 4
Escribe la función sumInput()
que:
Solicita valores al usuario mediante prompt
y almacena los valores en la matriz.
Termina de preguntar cuando el usuario ingresa un valor no numérico, una cadena vacía o presiona “Cancelar”.
Calcula y devuelve la suma de los elementos de la matriz.
PD: Un cero 0
es un número válido; no detenga la entrada en cero.
Ejecute la demostración
Tenga en cuenta el detalle sutil pero importante de la solución. No convertimos value
a número instantáneamente después prompt
, porque después de value = +value
no podríamos distinguir una cadena vacía (signo de stop) del cero (número válido). En su lugar, lo hacemos más tarde.
función sumaInput() { sean números = []; mientras (verdadero) { let value = Prompt("¿Un número por favor?", 0); // ¿deberíamos cancelar? if (valor === "" || valor === null || !isFinite(valor)) break; números.push(+valor); } sea suma = 0; for (sea el número de números) { suma += número; } suma de devolución; } alerta( sumaInput() );
importancia: 2
La entrada es una matriz de números, por ejemplo, arr = [1, -2, 3, 4, -9, 6]
.
La tarea es: encontrar el subarreglo contiguo de arr
con la suma máxima de elementos.
Escribe la función getMaxSubSum(arr)
que devolverá esa suma.
Por ejemplo:
getMaxSubSum([-1, 2, 3, -9]) == 5 (la suma de los elementos resaltados) getMaxSubSum([2, -1, 2, 3, -9]) == 6 getMaxSubSum([-1, 2, 3, -9, 11]) == 11 getMaxSubSum([-2, -1, 1, 2]) == 3 getMaxSubSum([100, -9, 2, -3, 5]) == 100 getMaxSubSum([1, 2, 3]) == 6 (tomar todo)
Si todos los elementos son negativos, significa que no tomamos ninguno (el subarreglo está vacío), por lo que la suma es cero:
getMaxSubSum([-1, -2, -3]) = 0
Intente pensar en una solución rápida: O(n 2 ) o incluso O(n) si puede.
Abra una caja de arena con pruebas.
Podemos calcular todas las subsumas posibles.
La forma más sencilla es tomar cada elemento y calcular la suma de todos los subarreglos a partir de él.
Por ejemplo, para [-1, 2, 3, -9, 11]
:
// A partir de -1: -1 -1 + 2 -1 + 2 + 3 -1 + 2 + 3 + (-9) -1 + 2 + 3 + (-9) + 11 // A partir de 2: 2 2 + 3 2 + 3 + (-9) 2 + 3 + (-9) + 11 // A partir de 3: 3 3 + (-9) 3 + (-9) + 11 // A partir de -9 -9 -9 + 11 // A partir del 11 11
El código es en realidad un bucle anidado: el bucle externo sobre los elementos de la matriz y el interno cuenta las subsumas comenzando con el elemento actual.
función getMaxSubSum(arr) { sea sumamáx = 0; // si no tomamos ningún elemento, se devolverá cero for (sea i = 0; i < arr.length; i++) { let sumFixedStart = 0; for (let j = i; j < arr.length; j++) { sumFixedStart += arr[j]; maxSum = Math.max(maxSum, sumaFixedStart); } } devolver sumamáx; } alerta( getMaxSubSum([-1, 2, 3, -9]) ); // 5 alerta( getMaxSubSum([-1, 2, 3, -9, 11]) ); // 11 alerta( getMaxSubSum([-2, -1, 1, 2]) ); // 3 alerta( getMaxSubSum([1, 2, 3]) ); // 6 alerta( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100
La solución tiene una complejidad temporal de O(n 2 ). En otras palabras, si aumentamos el tamaño de la matriz 2 veces, el algoritmo funcionará 4 veces más.
Para matrices grandes (1000, 10000 o más elementos), estos algoritmos pueden provocar una lentitud grave.
Recorramos la matriz y mantengamos la suma parcial actual de elementos en la variable s
. Si s
se vuelve negativo en algún momento, entonces asigne s=0
. El máximo de todos esos s
será la respuesta.
Si la descripción es demasiado vaga, consulte el código, es lo suficientemente breve:
función getMaxSubSum(arr) { sea sumamáx = 0; dejar suma parcial = 0; for (let item of arr) { // para cada elemento de arr suma parcial += elemento; // agregarlo a suma parcial sumamáx = Math.max(Sumamáx, sumaparcial); // recuerda el máximo if (SumaPartial < 0)SumaPartial = 0; // cero si es negativo } devolver sumamáx; } alerta( getMaxSubSum([-1, 2, 3, -9]) ); // 5 alerta( getMaxSubSum([-1, 2, 3, -9, 11]) ); // 11 alerta( getMaxSubSum([-2, -1, 1, 2]) ); // 3 alerta( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100 alerta( getMaxSubSum([1, 2, 3]) ); // 6 alerta( getMaxSubSum([-1, -2, -3]) ); // 0
El algoritmo requiere exactamente 1 pasada de matriz, por lo que la complejidad temporal es O (n).
Puede encontrar información más detallada sobre el algoritmo aquí: Problema de subarreglo máximo. Si aún no es obvio por qué funciona, entonces rastrea el algoritmo en los ejemplos anteriores, mira cómo funciona, eso es mejor que cualquier palabra.
Abra la solución con pruebas en un sandbox.