Finden gemeinsamer Elemente in zwei Arrays unterschiedlicher Größe
Lesezeit: 6 Minuten
Jijoy
Ich habe ein Problem, gemeinsame Elemente in zwei Arrays zu finden, und das ist von unterschiedlicher Größe.
Nimm , Array A1 von Größe n und Array A2 von Größe mund m != n
Bisher habe ich versucht, Listen einzeln zu durchlaufen und Elemente in eine andere Liste zu kopieren. Wenn das Element bereits enthält, markieren Sie es, aber ich weiß, dass es keine gute Lösung ist.
Wenn Sprache nicht wichtig ist: in c# ist list1.Intersect(list2)
Sortieren Sie die Arrays. Iterieren Sie sie dann mit zwei Zeigern, wobei Sie immer denjenigen vorrücken, der auf den kleineren Wert zeigt. Wenn sie auf gleiche Werte zeigen, haben Sie einen gemeinsamen Wert. Dies ist O(n log n+m log m), wobei n und m die Größen der beiden Listen sind. Es ist wie ein Zusammenführen Zusammenführen, sortierenaber wo Sie nur eine Ausgabe erzeugen, wenn die Werte, auf die gezeigt wird, gleich sind.
def common_elements(a, b):
a.sort()
b.sort()
i, j = 0, 0
common = []
while i < len(a) and j < len(b):
if a[i] == b[j]:
common.append(a[i])
i += 1
j += 1
elif a[i] < b[j]:
i += 1
else:
j += 1
return common
print 'Common values:', ', '.join(map(str, common_elements([1, 2, 4, 8], [1, 4, 9])))
Ausgänge
Common values: 1, 4
Wenn die Elemente nicht vergleichbar sind, werfen Sie die Elemente aus einer Liste in eine Hashmap und vergleichen Sie die Elemente in der zweiten Liste mit der Hashmap.
hm, was wäre die Ausgabe, falls dies der Fall wäre [1,1,1,2,2,4] und [1,1,1,2,2,2,5] ? Wenn ich richtig gelesen habe, sollten Sie nicht auch prüfen, ob es in bereits vorhanden ist common ? es sei denn, Sie bereinigen die Duplikate in common_elements später in Ihrem Code.
– Benutzer418748
25. Dezember 2010 um 9:24 Uhr
@Muggen 1, 1, 1, 2, 2. Wenn die Ausgabe unterschiedliche Werte sein soll, fügen Sie a hinzu while i < len(a) and j < len(b) and a[i] == b[j]: vor dem Inkrementieren i und j.
– moinudin
25. Dezember 2010 um 9:27 Uhr
Nett. +1. Welche Sprache ist das übrigens?
– Benutzer418748
25. Dezember 2010 um 9:42 Uhr
Dies ist die Reihenfolge (mlog m + nlog n), nicht m+n, da Sie beide Arrays sortieren.
– PrasannaK
3. September 2012 um 9:14 Uhr
Das Sortieren beider Arrays ist mlogm und nlogn sowie m + n für Ihren Algorithmus, also ist es O (mlogm + nlogn + m + n), also ist es insgesamt O (nlogn).
– slashdottir
29. Mai 2014 um 21:00 Uhr
Wenn Sie es effizient machen möchten, würde ich das kleinere Array in ein Hashset konvertieren und dann das größere Array iterieren und prüfen, ob das aktuelle Element im Hashset enthalten war. Die Hash-Funktion ist im Vergleich zum Sortieren von Arrays effizient. Das Sortieren von Arrays ist teuer.
Hier ist mein Beispielcode
import java.util.*;
public class CountTest {
public static void main(String... args) {
Integer[] array1 = {9, 4, 6, 2, 10, 10};
Integer[] array2 = {14, 3, 6, 9, 10, 15, 17, 9};
Set hashSet = new HashSet(Arrays.asList(array1));
Set commonElements = new HashSet();
for (int i = 0; i < array2.length; i++) {
if (hashSet.contains(array2[i])) {
commonElements.add(array2[i]);
}
}
System.out.println("Common elements " + commonElements);
}
}
Ausgabe:
Gemeinsame Elemente [6, 9, 10]
Schöne Lösung! Um es effizienter zu machen, können wir auch über das kleinere Array iterieren und Set des größeren Arrays erstellen.
– Nikhil Goyal
11. September 2018 um 8:50 Uhr
Gott sei Dank hat jemand diese Lösung gepostet. Ich dachte ich wäre der einzige der das gemacht hat.
Wirf dein A2-Array in ein HashSet und iteriere dann durch A1; wenn das aktuelle Element in der Menge ist, ist es ein gemeinsames Element. Dies benötigt O(m + n) Zeit und O(min(m, n)) Platz.
Sieht aus wie verschachtelte Schleifen:
commons = empty
for each element a1 in A1
for each element a2 in A2
if a1 == a2
commons.add(a1)
Sollte überhaupt keine Rolle spielen, wenn die Arrays die gleiche Größe haben.
Abhängig von der verwendeten Sprache und dem verwendeten Framework können Set-Operationen nützlich sein.
Es ist eigentlich O(n*m), wobei m und n die Größen der Arrays sind. Wenn Sie etwas über die Elemente wissen, können natürlich schnellere Algorithmen auftauchen (dh wenn sie Integer mit begrenztem Bereich enthalten oder sortiert sind).
– Eiko
25. Dezember 2010 um 9:21 Uhr
Ich bin kein Downvoter, aber es kann in O (n log n + m log m) gemacht werden und Ihr Ansatz ist O (m * n), was nicht gut ist.
– Said Amiri
28. Dezember 2010 um 12:25 Uhr
Entschuldigung, das ist Unsinn. Es wurde überhaupt nicht nach der schnellsten Umsetzung gefragt. Und bei vielen realen kleinen Anwendungen ist diese einfache, enge O(m*n)-Implementierung schneller als die anderen Ansätze. Und es ist auch Code mit geringem Wartungsaufwand. Wenn es weitere Einschränkungen zu berücksichtigen gilt, müssen wir sie kennen. Außerdem ist nicht klar, ob das Sortieren der Arrays überhaupt erlaubt ist (oder das Kopieren möglich ist).
– Eiko
28. Dezember 2010 um 14:20 Uhr
Gemeinschaft
Versuchen häufen beide Arrays, gefolgt von einer Zusammenführung, um den Schnittpunkt zu finden.
Java-Beispiel:
public static <E extends Comparable<E>>List<E> intersection(Collection<E> c1,
Collection<E> c2) {
List<E> result = new ArrayList<E>();
PriorityQueue<E> q1 = new PriorityQueue<E>(c1),
q2 = new PriorityQueue<E>(c2);
while (! (q1.isEmpty() || q2.isEmpty())) {
E e1 = q1.peek(), e2 = q2.peek();
int c = e1.compareTo(e2);
if (c == 0) result.add(e1);
if (c <= 0) q1.remove();
if (c >= 0) q2.remove();
}
return result;
}
Weitere Beispiele für das Zusammenführen finden Sie in dieser Frage.
Es ist eigentlich O(n*m), wobei m und n die Größen der Arrays sind. Wenn Sie etwas über die Elemente wissen, können natürlich schnellere Algorithmen auftauchen (dh wenn sie Integer mit begrenztem Bereich enthalten oder sortiert sind).
– Eiko
25. Dezember 2010 um 9:21 Uhr
Ich bin kein Downvoter, aber es kann in O (n log n + m log m) gemacht werden und Ihr Ansatz ist O (m * n), was nicht gut ist.
– Said Amiri
28. Dezember 2010 um 12:25 Uhr
Entschuldigung, das ist Unsinn. Es wurde überhaupt nicht nach der schnellsten Umsetzung gefragt. Und bei vielen realen kleinen Anwendungen ist diese einfache, enge O(m*n)-Implementierung schneller als die anderen Ansätze. Und es ist auch Code mit geringem Wartungsaufwand. Wenn es weitere Einschränkungen zu berücksichtigen gilt, müssen wir sie kennen. Außerdem ist nicht klar, ob das Sortieren der Arrays überhaupt erlaubt ist (oder das Kopieren möglich ist).
– Eiko
28. Dezember 2010 um 14:20 Uhr
Die Komplexität dessen, was ich gebe, ist O(N*M + N).
Beachten Sie auch, dass dies der Fall ist Pseudocode C Und dass es eindeutige Werte liefert.
z.B.[1,1,1,2,2,4] und [1,1,1,2,2,2,5] Wird zurückkehren [1,2]
Die Komplexität ist N*M Ursache der for Schleifen
+ N Ursache der Überprüfung, ob es bereits in der vorhanden ist ArrayCommon[] (welches ist n Größe für den Fall Array2[] enthält Daten, die einen Teil der duplizieren Array1[] Angenommen, N ist die Größe des kleineren Arrays (N < M).
int Array1[m] = { Whatever };
int Array2[n] = { Whatever };
int ArrayCommon[n] = { };
void AddToCommon(int data)
{
//How many commons we got so far?
static int pos = 0;
bool found = false;
for(int i = 0 ; i <= pos ; i++)
{
//Already found it?
if(ArrayCommon[i] == data)
{
found = true;
}
}
if(!found)
{
//Add it
ArrayCommon[pos] = data;
pos++;
}
}
for(int i = 0 ; i < m ; i++)
{
for(int j = 0 ; j < n ; j++)
{
//Found a Common Element!
if(Array1[i] == Array2[j])
AddToCommon(Array1[i]);
}
}
13118000cookie-checkFinden gemeinsamer Elemente in zwei Arrays unterschiedlicher Größeyes
Wenn Sprache nicht wichtig ist: in c# ist
list1.Intersect(list2)
– Said Amiri
25. Dezember 2010 um 17:43 Uhr
codereview.stackexchange.com/questions/189504/…
– Kreker
4. April 2020 um 22:24 Uhr