Entrenamiento de codilidad en equilibrio de cinta [cerrado]
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 que0 < 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.
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.
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;
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;
}