¿Qué es un algoritmo eficiente para encontrar el número de submatrices con el mismo número de 0s y 1s?

No estoy seguro de si este es el más eficiente, pero es lo que podría pensar de manera más intuitiva y después de una cierta optimización.

Tiene una complejidad de tiempo cuadrática. es decir, O (n ^ 2) y complejidad espacial constante.

El algoritmo es básicamente esto:

  1. Considere cada permutación de subarreglos a partir del primer conjunto, que incluirá los elementos de índice 0 y 1.
  2. Este es el truco: en lugar de volver al elemento con índice cero y agregar nuevamente los elementos de esta sub-matriz, lo que habría hecho que el algoritmo sea de tiempo cúbico, ya que los valores de los elementos son solo 0 y 1, puede mantener un total acumulado de los elementos visitados y ver si ese total es exactamente igual a la mitad del número de elementos visitados. Para cada mitad, incrementamos el número de subconjuntos del contador (la variable de respuesta en la implementación provista a continuación) en 1.
  3. Una vez que hemos iterado sobre la matriz una vez comenzando desde el índice 0 y considerando todas las sub-matrices posibles que comienzan desde el índice 0, es decir, [0–1], [0–2]… [0-n], comenzamos de nuevo desde índice 1. Por lo tanto, esto se convierte en una solución con un costo que es cuadrático en el tiempo.

A continuación se muestra una implementación en C #:

Si alguien tiene una manera de hacerlo en menos de un tiempo cuadrático, me encantaría saberlo.

utilizando el sistema;

// Complejidad del tiempo cuadrático: O (n ^ 2)
// Complejidad del espacio constante: O (1)
espacio de nombres Quora1
{
Programa de clase
{
vacío estático Main (string [] args)
{
var source = new [] {1, 0, 1, 0, 0, 1, 0, 0, 1, 1};

var answer = GetNumberOfSubarraysWithEqualZerosAndOnes (fuente);

Console.WriteLine (respuesta);
}

static int GetNumberOfSubarraysWithEqualZerosAndOnes (int [] fuente)
{
if (fuente == nulo)
lanzar una nueva ArgumentNullException (nameof (source));

var len = source.Length;

if (len == 1) devuelve 0;

respuesta var = 0;
var total = 0;

para (int i = 0; i <len; i ++)
{
para (int j = i; j <len; j ++)
{
total + = fuente [j];

si ((j – i)% 2! = 0)
{
if (total == ((j – i + 1) / 2))
respuesta ++;
}
}

total = 0;
}

respuesta de regreso;
}
}
}

More Interesting

Cómo convertirse en un profesional como desarrollador o ingeniero de API desarrollando usted mismo una API de pago completa

Go vs Node.js: ¿Cuál para una aplicación de iPhone que procesará rutas para Google Maps?

¿Cuáles son los principales problemas de escala relevantes para la ingeniería de software?

¿Qué hacen los instaladores de Windows? ¿Cuáles son los beneficios de utilizarlos en comparación con descomprimir solo?

¿Puedo obtener un trabajo de desarrollador de software en Bangalore por 3 meses de experiencia?

Siento que no puedo entender la codificación, ¿debería rendirme y encontrar otro interés?

¿Cuáles son las mejores prácticas para el aseguramiento de la calidad del software cuando se utilizan metodologías de desarrollo ágiles?

Cómo aprender habilidades de desarrollo de software si tengo experiencia en soporte de TI y actualmente trabajo como ingeniero DevOps

¿Qué es 'bot' y cómo funciona?

¿Por qué los gerentes de ingeniería en las compañías de software son tan particulares sobre la cantidad de años de experiencia durante la contratación?

Cómo convertirse en un programador más lento

¿Cuáles son algunos de tus algoritmos favoritos?

¿Cuáles son buenas herramientas de prueba para API?

¿Por qué la profesión de ingeniería de software carece de un organismo de autogobierno / defensa? Por ejemplo, los contadores tienen el AICPA, los abogados tienen bares.

Me gustaría diseñar una aplicación. ¿Es necesario aprender conceptos de bases de datos?