Entrenamiento de codilidad en equilibrio de cinta [cerrado]

Resuelto CTB asked hace 10 años • 21 respuestas

El otro día recibí una prueba de codilidad para un trabajo, por lo que he estado practicando usando algunos de los problemas de su página de capacitación. Enlace

Desafortunadamente, solo pude obtener 83/100 en la pregunta sobre el equilibrio de la cinta:

Se proporciona una matriz A no vacía con índice cero que consta de N números enteros. La matriz A representa números en una cinta.
Cualquier número entero P, tal que 0 < P < N, divide esta cinta en dos partes no vacías: A\[0], A\[1], …, A\[P − 1] and A\[P], A\[P + 1], …, A\[N − 1].
La diferencia entre las dos partes es el valor de: |(A\[0] + A\[1] + … + A\[P − 1]) − (A\[P] + A\[P + 1] + … + A\[N − 1])|
En otras palabras, es la diferencia absoluta entre la suma de la primera parte y la suma de la segunda parte.

Escriba una función que, dada una matriz A indexada a cero no vacía de N enteros, devuelva la diferencia mínima que se puede lograr.

Ejemplo: A[0] = 3 A[1] = 1 A[2] = 2 A[3] = 4 A[4] = 3
Podemos dividir esta cinta en cuatro lugares:
P = 1, diferencia = |3 − 10| = 7
P = 2, diferencia = |4 − 9| = 5
P = 3, diferencia = |6 − 7| = 1
P = 4, diferencia = |10 − 3| = 7
En este caso devolvería 1 ya que es la diferencia más pequeña.

N es un int, rango [2..100,000]; cada elemento de A es un int, rango [−1,000..1,000]. Debe tener una complejidad temporal O(n),

Mi código es el siguiente:

import java.math.*;
class Solution {
public int solution(int[] A) {
    
    long sumright = 0;
    long sumleft = 0;
    long ans;
    
    for (int i =1;i<A.length;i++)
        sumright += A[i];
    
    sumleft = A[0];
    ans =Math.abs(Math.abs(sumright)+Math.abs(sumleft));
    
    for (int P=1; P<A.length; P++)
    {
        if (Math.abs(Math.abs(sumleft) - Math.abs(sumright))<ans)
            ans = Math.abs(Math.abs(sumleft) - Math.abs(sumright));
        sumleft += A[P];
        sumright -=A[P];
    }
    return (int) ans;  
}

Me volví un poco loco con Math.abs. Las dos áreas de prueba en las que falla son "dobles" (que creo que son dos valores, -1000 y 1000, y "pequeñas". http://codility.com/demo/results/demo9DAQ4T-2HS/

Se agradecería cualquier ayuda. Quiero asegurarme de no cometer ningún error básico.

CTB avatar Oct 18 '13 23:10 CTB
Aceptado

Tu solución ya es O(N). Debes eliminar los abdominales de sumleft y sumright.

if (Math.abs( sumleft - sumright ) < ans)
{
  ans = Math.abs( sumleft - sumright );
}

También antes del segundo bucle for,

ans =Math.abs( sumleft - sumright );

Deberia de funcionar.

Abhishek Bansal avatar Oct 18 '2013 17:10 Abhishek Bansal

100% , en Javascript

var i, ll = A.length, tot = 0, upto = 0, min = Number.MAX_INT;

for (i=0; i<ll; i++) tot += A[i];

for (i=0; i<ll-1; i++)
{
    upto += A[i];
    var a1 = upto, a2 = tot - a1, dif = Math.abs(a1 - a2);
    if (dif < min)
         min = dif;
}

return min;
azurensces avatar Oct 01 '2014 16:10 azurensces

Encontré la solución perfecta para TapeEquilibrium de Cheng en Codesays . Lo traduje a Java para cualquiera que tenga curiosidad. La solución de Cheng alcanzó el 100% en Codility

    public int solution(int[] A) {

    // write your code in Java SE 7
    int N = A.length;

    int sum1 = A[0];
    int sum2 = 0;
    int P = 1;
    for (int i = P; i < N; i++) {
        sum2 += A[i];
    }
    int diff = Math.abs(sum1 - sum2);

    for (; P < N-1; P++) {
        sum1 += A[P];
        sum2 -= A[P];

        int newDiff = Math.abs(sum1 - sum2);
        if (newDiff < diff) {
            diff = newDiff;
        }
    }
    return diff;
}
vbg avatar Jun 03 '2014 23:06 vbg