test respuestas prueba programadores programacion para logica examen evaluacion entrevista cuestionario con basico aptitud java

java - respuestas - Prueba de programación-Codilidad-Dominator



test de logica de programacion (24)

¿Qué hay de ordenar la matriz primero? Luego compara los elementos intermedios, primero y último de la matriz ordenada para encontrar el elemento dominante.

public Integer findDominator(int[] arr) { int[] arrCopy = arr.clone(); Arrays.sort(arrCopy); int length = arrCopy.length; int middleIndx = (length - 1) /2; int middleIdxRight; int middleIdxLeft = middleIndx; if (length % 2 == 0) { middleIdxRight = middleIndx+1; } else { middleIdxRight = middleIndx; } if (arrCopy[0] == arrCopy[middleIdxRight]) { return arrCopy[0]; } if (arrCopy[middleIdxLeft] == arrCopy[length -1]) { return arrCopy[middleIdxLeft]; } return null; }

Acabo de tener un problema de codilidad, me resulta difícil y todavía estoy tratando de averiguar cómo se podrían haber cumplido las limitaciones de espacio y tiempo.

El problema es el siguiente: un miembro dominante en la matriz es uno que ocupa más de la mitad de las posiciones en la matriz, por ejemplo:

{3, 67, 23, 67, 67}

67 es un miembro dominante porque aparece en la matriz en 3/5 (> 50%) posiciones.

Ahora, se espera que proporcione un método que tome una matriz y devuelva un índice del miembro dominante si existe uno y -1 si no hay ninguno.

Fácil, ¿verdad? Bueno, podría haber resuelto el problema fácilmente si no fuera por las siguientes restricciones:

  • La complejidad del tiempo esperado es O (n)
  • La complejidad esperada del espacio es O (1)

Puedo ver cómo podría resolver esto por tiempo O (n) con complejidades de espacio O (n) así como tiempo O (n ^ 2) con complejidades de espacio O (1), pero ninguna que cumpla con el tiempo O (n) y O (1) espacio.

Realmente agradecería ver una solución a este problema. No se preocupe, la fecha límite ya pasó hace unas horas (solo tenía 30 minutos), así que no estoy tratando de hacer trampa. Gracias.


¿Tiene que ser un algoritmo particularmente bueno ? ;-)

static int dominant(final int... set) { final int[] freqs = new int[Integer.MAX_VALUE]; for (int n : set) { ++freqs[n]; } int dom_freq = Integer.MIN_VALUE; int dom_idx = -1; int dom_n = -1; for (int i = set.length - 1; i >= 0; --i) { final int n = set[i]; if (dom_n != n) { final int freq = freqs[n]; if (freq > dom_freq) { dom_freq = freq; dom_n = n; dom_idx = i; } else if (freq == dom_freq) { dom_idx = -1; } } } return dom_idx; }

( Esto fue principalmente para burlarse de los requisitos )


100%

import java.util.HashMap; import java.util.Map; class Solution { public static int solution(int[] A) { final int N = A.length; Map<Integer, Integer> mapOfOccur = new HashMap((N/2)+1); for(int i=0; i<N; i++){ Integer count = mapOfOccur.get(A[i]); if(count == null){ count = 1; mapOfOccur.put(A[i],count); }else{ mapOfOccur.replace(A[i], count, ++count); } if(count > N/2) return i; } return -1; } }


100% en PHP https://codility.com/demo/results/trainingVRQGQ9-NJP/

function solution($A){ if (empty($A)) return -1; $copy = array_count_values($A); // 3 => 7, value => number of repetition $max_repetition = max($copy); // at least 1 because the array is not empty $dominator = array_search($max_repetition, $copy); if ($max_repetition > count($A) / 2) return array_search($dominator, $A); else return -1; }


100% puntuación solución de JavaScript. Técnicamente es O (nlogn) pero aun así pasa.

function solution(A) { if (A.length == 0) return -1; var S = A.slice(0).sort(function(a, b) { return a - b; }); var domThresh = A.length/2; var c = S[Math.floor(domThresh)]; var domCount = 0; for (var i = 0; i < A.length; i++) { if (A[i] == c) domCount++; if (domCount > domThresh) return i; } return -1; }


A continuación se resuelve la solución en complejidad O (N).

public int solution(int A[]){ int dominatorValue=-1; if(A != null && A.length>0){ Hashtable<Integer, Integer> count=new Hashtable<>(); dominatorValue=A[0]; int big=0; for (int i = 0; i < A.length; i++) { int value=0; try{ value=count.get(A[i]); value++; }catch(Exception e){ } count.put(A[i], value); if(value>big){ big=value; dominatorValue=A[i]; } } } return dominatorValue; }


Adición de un tiempo de Java 100/100 O (N) con espacio O (1):

https://codility.com/demo/results/demoPNG8BT-KEH/

class Solution { public int solution(int[] A) { int indexOfCandidate = -1; int stackCounter = 0, candidate=-1, value=-1, i =0; for(int element: A ) { if (stackCounter == 0) { value = element; ++stackCounter; indexOfCandidate = i; } else { if (value == element) { ++stackCounter; } else { --stackCounter; } } ++i; } if (stackCounter > 0 ) { candidate = value; } else { return -1; } int countRepetitions = 0; for (int element: A) { if( element == candidate) { ++countRepetitions; } if(countRepetitions > (A.length / 2)) { return indexOfCandidate; } } return -1; } }

Si desea ver el código fuente de Java que está aquí , agregué algunos casos de prueba como comentarios al comienzo del archivo.


Adición de un tiempo de Java 100/100 O (N) con espacio O (1):

// you can also use imports, for example: import java.util.Stack; // you can write to stdout for debugging purposes, e.g. // System.out.println("this is a debug message"); class Solution { public int solution(int[] A) { // write your code in Java SE 8 int count = 0; Stack<Integer> integerStack = new Stack<Integer>(); for (int i = 0; i < A.length; i++) { if (integerStack.isEmpty()) { integerStack.push(A[i]); } else if (integerStack.size() > 0) { if (integerStack.peek() == A[i]) integerStack.push(A[i]); else integerStack.pop(); } } if (!integerStack.isEmpty()) { for (int i = 0; i < integerStack.size(); i++) { for (int j = 0; j < A.length; j++) { if (integerStack.get(i) == A[j]) count++; if (count > A.length / 2) return j; } count = 0; } } return -1; } }

Aquí está el result prueba de la codilidad.


Aquí está mi solución de C que puntúa 100%

int solution(int A[], int N) { int candidate; int count = 0; int i; // 1. Find most likely candidate for the leader for(i = 0; i < N; i++){ // change candidate when count reaches 0 if(count == 0) candidate = i; // count occurrences of candidate if(A[i] == A[candidate]) count++; else count--; } // 2. Verify that candidate occurs more than N/2 times count = 0; for(i = 0; i < N; i++) if(A[i] == A[candidate]) count++; if (count <= N/2) return -1; return candidate; // return index of leader }


Aquí hay una versión 100% fácil de leer en Objective-c

if (A.count > 100000) return -1; NSInteger occur = 0; NSNumber *candidate = nil; for (NSNumber *element in A){ if (!candidate){ candidate = element; occur = 1; continue; } if ([candidate isEqualToNumber:element]){ occur++; }else{ if (occur == 1){ candidate = element; continue; }else{ occur--; } } } if (candidate){ occur = 0; for (NSNumber *element in A){ if ([candidate isEqualToNumber:element]) occur++; } if (occur > A.count / 2) return [A indexOfObject:candidate]; } return -1;


Considera esta solución 100/100 en Ruby:

# Algorithm, as described in https://codility.com/media/train/6-Leader.pdf: # # * Iterate once to find a candidate for dominator. # * Count number of candidate occurences for the final conclusion. def solution(ar) n_occu = 0 candidate = index = nil ar.each_with_index do |elem, i| if n_occu < 1 # Here comes a new dominator candidate. candidate = elem index = i n_occu += 1 else if candidate == elem n_occu += 1 else n_occu -= 1 end end # if n_occu < 1 end # Method result. -1 if no dominator. # Count number of occurences to check if candidate is really a dominator. if n_occu > 0 and ar.count {|_| _ == candidate} > ar.size/2 index else -1 end end #--------------------------------------- Tests def test sets = [] sets << ["4666688", [1, 2, 3, 4], [4, 6, 6, 6, 6, 8, 8]] sets << ["333311", [0, 1, 2, 3], [3, 3, 3, 3, 1, 1]] sets << ["313131", [-1], [3, 1, 3, 1, 3, 1]] sets << ["113333", [2, 3, 4, 5], [1, 1, 3, 3, 3, 3]] sets.each do |name, one_of_expected, ar| out = solution(ar) raise "FAILURE at test #{name.inspect}: #{out.inspect} not in #{expected.inspect}" if not one_of_expected.include? out end puts "SUCCESS: All tests passed" end


Creo que esta pregunta ya se ha resuelto en alguna parte. La solución "oficial" debe ser:

public int dominator(int[] A) { int N = A.length; for(int i = 0; i< N/2+1; i++) { int count=1; for(int j = i+1; j < N; j++) { if (A[i]==A[j]) {count++; if (count > (N/2)) return i;} } } return -1; }


DO#

int dominant = 0; int repeat = 0; int? repeatedNr = null; int maxLenght = A.Length; int halfLenght = A.Length / 2; int[] repeations = new int[A.Length]; for (int i = 0; i < A.Length; i++) { repeatedNr = A[i]; for (int j = 0; j < A.Length; j++) { if (repeatedNr == A[j]) { repeations[i]++; } } } repeatedNr = null; for (int i = 0; i < repeations.Length; i++) { if (repeations[i] > repeat) { repeat = repeations[i]; repeatedNr = A[i]; } } if (repeat > halfLenght) dominant = int.Parse(repeatedNr.ToString());


En Python, tenemos la suerte de que algunas personas inteligentes se hayan molestado en implementar ayudantes eficientes utilizando C y lo hayan enviado a la biblioteca estándar. Las collections.Counter Encuentro es útil aquí.

>>> data = [3, 67, 23, 67, 67] >>> from collections import Counter >>> counter = Counter(data) # counter accepts any sequence/iterable >>> counter # dict like object, where values are the occurrence Counter({67: 3, 3: 1, 23: 1}) >>> common = counter.most_common()[0] >>> common (67, 3) >>> common[0] if common[1] > len(data) / 2.0 + 1 else -1 67 >>>

Si prefieres una función aquí hay una ...

>>> def dominator(seq): counter = Counter(seq) common = counter.most_common()[0] return common[0] if common[1] > len(seq) / 2.0 + 1 else -1 ... >>> dominator([1, 3, 6, 7, 6, 8, 6]) -1 >>> dominator([1, 3, 6, 7, 6, 8, 6, 6]) 6


En Ruby puedes hacer algo como

def dominant(a) hash = {} 0.upto(a.length) do |index| element = a[index] hash[element] = (hash[element] ? hash[element] + 1 : 1) end res = hash.find{|k,v| v > a.length / 2}.first rescue nil res ||= -1 return res end


Esta es la solución en VB.NET con un rendimiento del 100%.

Dim result As Integer = 0 Dim i, ladderVal, LadderCount, size, valCount As Integer ladderVal = 0 LadderCount = 0 size = A.Length If size > 0 Then For i = 1 To size - 1 If LadderCount = 0 Then LadderCount += 1 ladderVal = A(i) Else If A(i) = ladderVal Then LadderCount += 1 Else LadderCount -= 1 End If End If Next valCount = 0 For i = 0 To size - 1 If A(i) = ladderVal Then valCount += 1 End If Next If valCount <= size / 2 Then result = 0 Else LadderCount = 0 For i = 0 To size - 1 If A(i) = ladderVal Then valCount -= 1 LadderCount += 1 End If If LadderCount > (LadderCount + 1) / 2 And (valCount > (size - (i + 1)) / 2) Then result += 1 End If Next End If End If Return result

Ver la corrección y el rendimiento del código.


Esta es mi respuesta en Java: almaceno un conteo en una matriz separada que cuenta duplicados de cada una de las entradas de la matriz de entrada y luego mantiene un puntero a la posición de la matriz que tiene la mayoría de duplicados. Este es el dominador.

private static void dom(int[] a) { int position = 0; int max = 0; int score = 0; int counter = 0; int[]result = new int[a.length]; for(int i = 0; i < a.length; i++){ score = 0; for(int c = 0; c < a.length;c++){ if(a[i] == a[c] && c != i ){ score = score + 1; result[i] = score; if(result[i] > position){ position = i; } } } } //This is just to facilitate the print function and MAX = the number of times that dominator number was found in the list. for(int x = 0 ; x < result.length-1; x++){ if(result[x] > max){ max = result[x] + 1; } } System.out.println(" The following number is the dominator " + a[position] + " it appears a total of " + max); }


Esta pregunta parece difícil si un pequeño truco no viene a la mente :). Encontré este truco en este documento de codilidad: https://codility.com/media/train/6-Leader.pdf .

La solución lineal se explica al final de este documento.

Implementé el siguiente programa java que me dio una puntuación de 100 en las mismas líneas.

public int solution(int[] A) { Stack<Integer> stack = new Stack<Integer>(); for (int i =0; i < A.length; i++) { if (stack.empty()) stack.push(new Integer(A[i])); else { int topElem = stack.peek().intValue(); if (topElem == A[i]) { stack.push(new Integer(A[i])); } else { stack.pop(); } } } if (stack.empty()) return -1; int elem = stack.peek().intValue(); int count = 0; int index = 0; for (int i = 0; i < A.length; i++) { if (elem == A[i]) { count++; index = i; } } if (count > ((double)A.length/2.0)) return index; else return -1; }


Googled "miembro dominante de la computación de la matriz", fue el primer resultado . Vea el algoritmo descrito en la página 3.

element x; int count ← 0; For(i = 0 to n − 1) { if(count == 0) { x ← A[i]; count++; } else if (A[i] == x) count++; else count−−; } Check if x is dominant element by scanning array A

Básicamente, observe que si encuentra dos elementos diferentes en la matriz, puede eliminarlos sin cambiar el elemento dominante en el resto. Este código simplemente sigue eliminando pares de elementos diferentes, manteniendo un registro de la cantidad de veces que ha visto el único elemento no pareado restante.


La solución de @Keith Randall no funciona para {1,1,2,2,3,2,2}

Su solución fue:

element x; int count ← 0; For(i = 0 to n − 1) { if(count == 0) { x ← A[i]; count++; } else if (A[i] == x) count++; else count−−; } Check if x is dominant element by scanning array A

Lo convertí en java de la siguiente manera:

int x = 0; int count = 0; for(int i = 0; i < (arr.length - 1); i++) { if(count == 0) { x = arr[i]; count++; } else if (arr[i] == x) count++; else count--; } return x;

Fuera de venta: 3 Esperado: 2


Solución Java con puntaje 100%.

public int solution(int[] array) { int candidate=0; int counter = 0; // Find candidate for leader for(int i=0; i<array.length; i++){ if(counter == 0) candidate = i; if(array[i] == array[candidate]){ counter++; }else { counter--; } } // Count candidate occurrences in array counter = 0; for(int i=0; i<array.length; i++){ if(array[i] == array[candidate]) counter++; } // Check that candidate occurs more than array.lenght/2 return counter>array.length/2 ? candidate : -1; }


pruebo mi código su trabajo bien en longitudes de arrays entre 2 y 9

public static int sol (int []a) { int count = 0 ; int candidateIndex = -1; for (int i = 0; i <a.length ; i++) { int nextIndex = 0; int nextOfNextIndex = 0; if(i<a.length-2) { nextIndex = i+1; nextOfNextIndex = i+2; } if(count==0) { candidateIndex = i; } if(a[candidateIndex]== a[nextIndex]) { count++; } if (a[candidateIndex]==a[nextOfNextIndex]) { count++; } } count -- ; return count>a.length/2?candidateIndex:-1; }


Encuentre la mediana con BFPRT , también conocida como mediana de medianas (tiempo O (N), espacio O (1)). Luego escanee a través de la matriz: si un número domina, la mediana será igual a ese número. Recorra la matriz y cuente el número de instancias de ese número. Si es más de la mitad de la matriz, es el dominador. De lo contrario, no hay dominador.


class Program { static void Main(string[] args) { int []A= new int[] {3,6,2,6}; int[] B = new int[A.Length]; Program obj = new Program(); obj.ABC(A,B); } public int ABC(int []A, int []B) { int i,j; int n= A.Length; for (j=0; j<n ;j++) { int count = 1; for (i = 0; i < n; i++) { if ((A[j]== A[i] && i!=j)) { count++; } } int finalCount = count; B[j] = finalCount;// to store the no of times a number is repeated } // int finalCount = count / 2; int finalCount1 = B.Max();// see which number occurred max times if (finalCount1 > (n / 2)) { Console.WriteLine(finalCount1); Console.ReadLine(); } else { Console.WriteLine("no number found"); Console.ReadLine(); } return -1; } }