8
votes

Trouvez la plus petite fenêtre de la matrice d'entrée contenant tous les éléments du tableau de requêtes

Problème: Compte tenu d'un réseau d'entrées d'entiers de taille N, et d'une gamme de requêtes d'entiers de taille K, trouvez la plus petite fenêtre de la matrice d'entrée contenant tous les éléments du tableau de requêtes et dans le même ordre.

J'ai essayé en dessous de l'approche. P>

public static void SmallestWindow(int[] inputArray, int[] queryArray)
    {
        Dictionary<int, HashSet<int>> dict = new Dictionary<int, HashSet<int>>();

        int index = 0;
        foreach (int i in queryArray)
        {
            HashSet<int> hash = new HashSet<int>();
            foreach (int j in inputArray)
            {
                index++;
                if (i == j)
                    hash.Add(index); 
            }
            dict.Add(i, hash);
            index = 0;
        }
      // Need to perform action in above dictionary.??
    }


4 commentaires

Si QueryARray est {2, 8, 0} Quelle est la sortie attendue? Indices [0-4] ou indices [2-4] ?


@Ani - Je pense que devrait être [2-4] , qui est le plus court.


oui, devrait être [2-4] car c'est la plus petite fenêtre


CAN QUERYARRAY contient la même valeur multiple plusieurs fois?


8 Réponses :


0
votes

Je ne vois pas comment utiliser hashset et dictionnaire vous aidera à cela. Étiez-moi confronté à ce problème, j'irais très différemment.

Un moyen de le faire (pas la manière la plus efficace) est indiquée ci-dessous. Ce code rend l'hypothèse selon laquelle QueryARray contient au moins deux éléments. xxx

avec un certain travail, cela pourrait être rendu plus efficace. Par exemple, si "QueryARray" contient [1, 2, 3] et INPORTARRAY contient [1, 7, 4, 9, 1, 3, 6, 4, 1, 8, 2, 3] , le code ci-dessus trouvera trois correspondances (à partir de la position 0, 4 et 8). Le code légèrement plus intelligent pourrait déterminer que lorsque le 1 à la position 4 est trouvé, car aucun 2 a été trouvé avant cela, que toute séquence commençant à la première position serait plus longue que La séquence commençant à la position 4, et donc de court-circuit la première séquence et recommencez à la nouvelle position. Qui complique un peu le code, cependant.


0 commentaires

4
votes

L'algorithme:
Pour chaque élément du tableau de requêtes, stockez sur une carte M (V → (I, P)), v est l'élément, je serai un index dans la matrice d'entrée, P est la position dans le réseau de requêtes. (l'index dans la matrice d'entrée pour certains p est le plus important de ce que la requête [0..p] est une subséquence de l'entrée [i..Curr])

Itérer à travers le tableau.
Si la valeur est le premier terme du tableau de requêtes: stockez l'index actuel comme i.
Sinon: Stockez la valeur de l'index de l'élément précédent dans le tableau de requêtes, par ex. m [curval] .i = m [requête [m [m [curval] .p-1]]. i .
Si la valeur est le dernier terme: vérifiez si [i..Curr] est un nouveau meilleur.

complexité
La complexité de ceci est O (n) , où n est la taille de la matrice d'entrée.

n.b.
Ce code s'attend à ce qu'aucun élément ne soit répété dans le tableau de requêtes. Pour répondre à cela, nous pouvons utiliser une carte M (v → la liste de ((i, p))). Ceci est O (n hc (q)), où HC (q) est le nombre de Mode pour le tableau de requêtes ..
Mieux vaut mieux utiliser M (V → ListeOf ((LinkedList (I), P))). Lorsque des éléments répétés se produisent consécutivement dans le tableau de requêtes, nous utilisons une liste liée. Mise à jour de ces valeurs alors devient O (1). La complexité est alors O (n hc (d (q))), où d (q) est q avec des termes consécutifs fusionnés.

Mise en œuvre
Exemple de mise en œuvre Java est disponible ici . Cela ne fonctionne pas pour des éléments répétés dans le tableau de requêtes, ni la vérification des erreurs, etc.


2 commentaires

Belle solution. Je trouve du mal à comprendre ce que vous faites ici: currapair.i = m.get (Query [currapair.p - 1]). I et celui-ci - si (CODPAIR. P == Query.length - 1 && CARDPAIR.I! = -1 && I - VARDPAIR.I - Pouvez-vous expliquer en anglais clair? :)


En outre, votre solution échoue à cette entrée: entrée : 2 3 4 5 2 Query : 2 4 5 - La réponse doit être 2..4 , mais votre solution donne 0..3



0
votes

Vous ne voulez pas un hashset, mais un arbre ou un tableau trié) comme valeur dans le dictionnaire; Le dictionnaire contient des mappages des valeurs que vous trouvez dans la liste d'entrée à la liste (triée) des indices où cette valeur apparaît.

alors vous faites ce qui suit

  • Recherchez la première entrée de la requête. Choisissez l'index le plus bas où il apparaît.
  • Recherchez la deuxième entrée; Choisissez l'entrée la plus basse supérieure à l'indice du premier.
  • lève la troisième; Choisissez le plus bas supérieur à la seconde. (Etc.)
  • Lorsque vous atteignez la dernière entrée de la requête (1 + l'index de la dernière-Index - Premier Index) est la taille de la plus petite correspondance.
  • choisissez maintenant le deuxième index de la première requête, répétez, etc.
  • Choisissez le plus petit match trouvé de l'un des indices de départ.

    (Notez que la "entrée la plus basse supérieure" est une opération fournie avec des arbres triés ou peut être trouvée via une recherche binaire sur une matrice triée.)

    La complexité de ceci est approximativement O (m * n * journal n) m est la longueur de la requête et n est Le nombre moyen d'indices au cours desquels une valeur donnée apparaît dans la matrice d'entrée. Vous pouvez modifier la stratégie en choisissant la valeur de la tuyau de requête qui apparaît moins souvent pour le point de départ et de monter et de descendre de là; S'il y a k de ces entrées ( k <= n ) alors la complexité est o (m * k * log n) .


0 commentaires

0
votes

Après que vous ayez toutes les positions (index) dans l'INPORTARRAY:

static void Go(int depth)
{
    if (depth == pairs.Length)
    {
        results.Add(currResult.Reverse().ToArray());
    }
    else
    {
        var indexes = pairs[depth].Indexes;
        for (int i = 0; i < indexes.Length; i++)
        {
            if (depth == 0 || indexes[i] > currResult.Last())
            {
                currResult.Push(indexes[i]);
                Go(depth + 1);
                currResult.Pop();
            }
        }
    }
}


0 commentaires

0
votes

algorithme:

  1. Obtenez tous les index dans l'Inpurateur de toutes les valeurs QuererieArray li>
  2. Les commandez-les ascendant par index li>
  3. en utilisant chaque index (x) comme un démarrage point trouver le premier index supérieur (y) tel que le segment INTERTARRAY [X-Y] contient tout Valeurs QueryArray Li>
  4. Ne conserve que ces segments qui ont les articles QueryARray dans l'ordre LI>
  5. commandez les segments par leurs longueurs, ascendant li> ol>

    C # implémentation: p>

    Obtenez d'abord tous les index dans l'intrigier de toutes les valeurs QuererieArray et commandez-les ascendant par index. P>

    Smallest window is indexes 3 to 8
    


0 commentaires

0
votes

Merci à tous pour vos contributions. J'ai changé mon code un peu et trouvai le travail. Bien que cela ne soit pas très efficace, mais je suis heureux de résoudre en utilisant ma tête :). S'il vous plaît donner à vos commentaires

Voici ma classe de paire avec un numéro et une position comme variable xxx

voici une méthode qui retournera la liste de toutes paires. xxx

voici la ligne de code dans la méthode principale xxx


0 commentaires

0
votes

Il convient de noter que ce problème est lié au problème de la recherche courante la plus longue, donc à venir avec des algorithmes qui fonctionnent mieux que O (n ^ 2) temps dans le cas général avec des doublons serait difficile.


0 commentaires

0
votes

Juste au cas où quelqu'un est intéressé par une implémentation C ++ avec O (NLog (k)) xxx pré>

ici le principal pour l'appeler. p>

    #include <iostream>
    #include <vector>
    #include <map>

    using namespace std;

    int main() {
        vector<int> input;
        input.push_back(2);
        input.push_back(5);
        input.push_back(2);
        input.push_back(8);
        input.push_back(0);
        input.push_back(1);
        input.push_back(4);
        input.push_back(7);

        vector<int> query1;
        query1.push_back(2);
        query1.push_back(8);
        query1.push_back(0);

        vector<int> query2;
        query2.push_back(2);
        query2.push_back(1);
        query2.push_back(7);

        vector<int> query3;
        query3.push_back(1);
        query3.push_back(4);

        findMinWindow(input, query1);
        findMinWindow(input, query2);
        findMinWindow(input, query3);
    }


0 commentaires