web-dev-qa-db-fra.com

Somme de tableau unique unique

J'ai reçu une question d'entretien et mon algorithme n'a réussi que des exemples de tests et n'a pas réussi tous les tests.

Question: Étant donné un tableau entier trié, renvoyez la somme du tableau afin que chaque élément soit unique en ajoutant des nombres aux éléments en double afin que la somme des éléments uniques soit minimale. 

Par exemple, si tous les éléments du tableau sont uniques, renvoyez la somme . Si certains éléments sont dupliqués, incrémentez-les pour vous assurer que tous les éléments sont uniques, de sorte que la somme de ces éléments uniques soit minimale.

Quelques exemples:

  • input1[] = { 2, 3, 4, 5 } => return 19 = 2 + 3 + 4 + 5 (tous les éléments sont uniques, ajoutez-les donc)
  • input2[] = { 1, 2, 2 } => return 6 = 1 + 2 + 3 (l'index 2 est en double, donc incrémentez-le) 
  • input3[] = { 2, 2, 4, 5 } => return 14 = 2 + 3 + 4 + 5 (l'index 1 est en double, donc incrémentez-le)

Ces trois exemples sont des exemples dans la question. Mon algorithme simple est le suivant et a réussi les trois exemples donnés, mais n'a pas réussi d'autres cas où je ne pouvais pas voir les entrées.

static int minUniqueSum(int[] A) {
    int n = A.length;


    int sum = A[0];
    int prev = A[0];

    for( int i = 1; i < n; i++ ) {
        int curr = A[i];

        if( prev == curr ) {
            curr = curr+1;
            sum += curr;
        }
        else {
            sum += curr;
        }
        prev = curr;
    }

    return sum;
}

Je ne pouvais pas voir d'autres entrées auxquelles cet algorithme avait échoué . Ce que je peux penser aux autres exemples d'entrée est

{1, 1, 1, 1}  --> {1, 2, 3, 4}
{1, 1, 2, 2, 3, 3, 3} --> {1, 2, 3, 4, 5, 6, 7}

{1, 2, 4, 4, 7, 7, 8} --> I think this should be {1, 2, 3, 4, 6, 7, 8}  and my algorithm fails in this example because my algorithm has {1, 2, 4, 5, 7, 8, 9} whose sum is not minimum 

Quels sont quelques autres cas de test et un algorithme qui peut passer tous les cas?

Certaines personnes se plaignent que la question n'est pas claire. J'aimerais vous informer du problème. Il n'y avait pas de description claire du nombre ajouté si on ne l'autorisait que de manière positive ou positive et négative. À partir de trois exemples avec entrée et sortie, et de quelques autres cas d'entrée et de sortie que vous n'êtes pas autorisé à voir, écrivez un programme pour transmettre tous les autres cas d'entrée/sortie non vus. C'était la question.

8
user2761895

Votre algorithme échouera dans les cas avec plus de valeurs répétées, par exemple

2, 2, 2

Vous auriez 7 au lieu de 9.

Un correctif minimal utilisant votre algorithme serait:

static int minUniqueSum(int[] A) {
    int n = A.length;

    int sum = A[0];
    int prev = A[0];

    for( int i = 1; i < n; i++ ) {
        int curr = A[i];

        if( prev >= curr ) {
            curr = prev+1;
        }
        sum += curr;
        prev = curr;
    }

    return sum;
}

* Comme indiqué dans les commentaires, pas besoin de trier un tableau déjà trié.

5
Amit

J'ai fait comme ça, sans sorte.

    // Complete the getMinimumUniqueSum function below.
static int getMinimumUniqueSum(int[] arr) {

 int sum = 0;

 ArrayList < Integer > arrayList = new ArrayList < Integer > (arr.length);

 arrayList.add(arr[0]);


 for (int i = 1; i < arr.length; i++) {

  int val = arr[i];

  while (arrayList.contains(val)) {

   val++;
  }

  arrayList.add(val);

 }



 for (int i = 0; i < arrayList.size(); i++) {
  sum += arrayList.get(i);
 }

 return sum;
}

Et il a réussi tous les (13) cas de test.

1
CursedChico

Si vous êtes autorisé à ajouter des valeurs négatives à n’importe laquelle des entrées, le minimum n’est que le Nième nombre triangulaire, N étant le nombre d’éléments du tableau. (Je suppose que nous ne traitons que des nombres positifs pour le tableau ajusté car nous pourrions le rendre arbitrairement petit (négatif) autrement.

Votre algorithme consiste donc simplement à rechercher une paire de valeurs consécutives identiques. Si non trouvé, retourne la somme sinon N * (N + 1) / 2.


Si au contraire, il est vrai que seuls les éléments en double peuvent être ajustés, il convient alors de rechercher des trous entre les éléments consécutifs et de les remplir avec des valeurs précédemment "en file d'attente". Les valeurs réelles des éléments "en file d'attente" sont sans importance et seul un compteur est nécessaire. Vous trouverez ci-dessous une solution en C # où je suppose que les ajustements d’éléments doivent être des valeurs positives. Cela signifie donc que nous ne pouvons pas revenir en arrière et combler les trous inutilisés, ce qui simplifie le problème.

int F()
{
    int[] a = {2, 2, 2, 3, 8, 9}; // sorted list

    int n = 0; /* num */   int p = 0; /* prev; zero is an invalid value in the list */
    int q = 0; /* queue */ int s = 0; /* sum */

    for (int i = 1; i < a.Length; i++)
    {
        n = a[i];
        if (n == p)
            q++; // increment queue on duplicate number
        else
        {
            // for every hole between array values, decrement queue and add to the sum
            for (int j = 1; q > 0 && j < n - p; j++, q--)
                s += p + j;
            s += (p = n);
        }
    }
    // flush the queue
    for (; q > 0; q--)
        s += ++n;

    return s;
}

Votre exemple {1, 2, 4, 4, 7, 7, 8} suggère que l'hypothèse précédente n'est pas valide. Alors je suis allé de l'avant et j'ai écrit une version qui utilise une file d'attente pour stocker les trous ignorés pour un remplissage ultérieur. Ce n'est pas vraiment douloureux et sa structure est très similaire, mais c'est peut-être encore trop pour la plupart des interviews.

using System.Collections.Generic;
int F2()
{
    int[] a = {1, 1, 8, 8, 8, 8, 8}; // sorted list

    int n = 0; /* num */   int p = 0; // prev; zero is an invalid value in the list
    int q = 0; /* queue */ int s = 0; // sum
    Queue<int> h = new Queue<int>(); // holes

    for (int i = 1; i < a.Length; i++)
    {
        n = a[i];
        if (n == p)
            q++; // increment queue on duplicate number
        else
        {
            for (int j = 1; j < n - p; j++)
                if (h.Count <= q + a.Length - i) // optimization
                    h.Enqueue(p + j);
            s += (p = n);
        }
    }
    // flush the queue
    for (; q > 0; q--)
        s += h.Count > 0 ? h.Dequeue() : ++n;

    return s;
}

Essayez les deux ici: http://rextester.com/APO79723

0
shawnt00

Vous pouvez essayer le code ci-dessous. 

int a[] = {1, 1 , 1};
ArrayList<Integer> arr = new ArrayList<Integer>();
HashMap hash = new HashMap();
for(int i=0;i<a.length;i++){
    arr.add(a[i]);
}
int sum = 0;
hash.put(0, arr.get(0));
sum = (int) hash.get(0);
for(int i=1;i<arr.size();i++){
    for(int j=1;j<=a.length;j++){
        if(hash.containsValue((arr.get(i)))){
            arr.set(i, arr.get(i)+1);
        }else{
            hash.put(i, arr.get(i));
            sum += (int) hash.get(i);
            break;
        }
    }
}

System.out.println(sum);

PS: Même si cette question m'a été posée lors de mon entretien, le code ci-dessus a réussi tous les tests. 

0
Shruti Priya
int a[] = {1,2,2,3,5,6,6,6,6 }; So what would be elements in array for sum
As per above problem statement it would be {1,2,3,4,5,6,7,8,9 }

Solution
public static void uniqueSum(){
        int a[] = {1,2,2,3,5,6,6,6,6 };
        int n = a.length;
        int sum = a[0];
        int prv=a[0];
        for(int i=1; i<n;i++){
            int cur = a[i];
            if(cur==prv){
                cur = cur+1;
                sum+= cur;
                System.out.print("--"+cur);
            }else{
                if(cur<prv){
                    cur = prv +1;
                }
                sum += cur;
            }
            prv = cur;
        }
        System.out.println("===================== "+sum);
    }
0
Rajeev Rathor

public static int minSum (int arr []) {

    for(int i=0; i<arr.length-1;i++){

        if(arr[i]==arr[i+1]){

            arr[i+1]= arr[i+1]+1;
        }
    }

    int sum=0;

    for(int i=0; i<arr.length;i++){

        sum=sum+arr[i];
    }

    System.out.println("sum: "+sum);
    return sum;
}
0
Kunal Gaurav

L’utilisation de Collections en Java aide beaucoup,

Ma clé dans hashmap correspond aux éléments du tableau et la valeur au non. de compte comme il apparaît dans le tableau.

package uniquesum;
import Java.util.*;
public class Uniquesum {
static HashMap<Integer, Integer> hp = new HashMap<Integer, Integer>();
    static int Sum(int arr[]){
        int sum=0;
        Arrays.sort(arr);
        hp.put(arr[0], 1);
        for(int i=1; i<arr.length; i++){
            if(hp.containsKey(arr[i])){

                Integer val = hp.get(arr[i]);
                hp.put(arr[i], val+1);
                hp.put(arr[i]+val, 1);                
            }
            else{
                hp.put(arr[i], 1);
            }
        }

        for(Map.Entry m:hp.entrySet()){
            sum = sum + (int)m.getKey();
        }
        return sum;
    }
    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int arr[] = new int [n];
        for(int i=0; i<n;i++){

        arr[i] = scan.nextInt();
        }

        System.out.println("Sum is " + Sum(arr));


    }

}
0