Viene fornito come input una matrice non ordinata di n numeri distinti, dove n è una potenza di 2. Fornire un algoritmo che identifica il secondo più grande numero nell'array e che utilizza al massimo n + log₂ (n) -2 confronti.Trova il secondo numero più grande nella matrice al più n + log₂ (n) -2 confronti
risposta
- Iniziare confrontando gli elementi della matrice di elementi n in posizioni dispari e pari e determinando l'elemento più grande di ciascuna coppia. Questo passaggio richiede n/2 confronti. Ora hai solo n/2 elementi. Continua i confronti a coppie per ottenere n/4, n/8, ... elementi. Fermati quando viene trovato l'elemento più grande. Questo passaggio richiede un totale di n/2 + n/4 + n/8 + ... + 1 = confronti n-1.
- Durante il passaggio precedente, l'elemento più grande è stato immediatamente confrontato con log₂ (n) altri elementi. È possibile determinare il più grande di questi elementi nei confronti di log₂ (n) -1. Quello sarebbe il secondo numero più grande dell'array.
Esempio: array di 8 numeri [10,9,5,4,11,100,120,110].
Confronto sul livello 1: [10,9] -> 10 [5,4] -> 5, [11,100] -> 100, [120,110] -> 120.
Confronto sul livello 2: [10,5] -> 10 [100,120] -> 120.
Confronti sul livello 3: [10,120] -> 120.
Il numero massimo è 120. È stato immediatamente confrontato con: 10 (livello 3), 100 (livello 2), 110 (livello 1).
Il passaggio 2 dovrebbe trovare il massimo di 10, 100 e 110. Che è 110. Questo è il secondo elemento più grande.
Puoi per favore approfondire di più. Considera un esempio che ho un array di 8 numeri 10,9,5,4,11,100,120,110 Ora, se faccio un paio di confronti saggi, sarà [10,9] -> 10 [5,4] -> 5, [11,100] -> 100, [120,110] -> 120 ora 110 sono persi in quanto non si otterrà alcun confronto. –
@AmitDeshpande, 110 non è perso. Infatti, viene confrontato con il valore massimo (120). Quindi dovrebbe essere incluso nel set di elementi da confrontare l'uno con l'altro sul passo 2 dell'algoritmo. –
scusate ma non è ancora chiaro con me aggiungerà un altro confronto su ogni livello che porta al numero di confronti con n + n/2-2 non il risultato atteso. Puoi per favore darmi un esempio in modo che io possa capirlo meglio. –
il problema è: diciamo, nel livello di confronto 1, l'algoritmo deve essere ricordato di tutto l'elemento dell'array perché il più grande non è ancora noto, quindi, secondo, infine, terzo. Continuando a tenere traccia di questi elementi tramite l'assegnazione, si invocherà un'ulteriore assegnazione di valore e in seguito, quando il più grande è noto, sarà necessario considerare anche il rintracciamento. Di conseguenza, non sarà significativamente più veloce del semplice algoritmo di confronto 2N-2. Inoltre, poiché il codice è più complicato, è necessario anche pensare a potenziali tempi di debug.
es: in PHP, durata di confronto vs assegnazione valore approssimativamente a dire: Confronto: (11-19) per un'assegnazione di valori: 16.
I shall give some examples for better understanding. :
example 1 :
>12 56 98 12 76 34 97 23
>>(12 56) (98 12) (76 34) (97 23)
>>> 56 98 76 97
>>>> (56 98) (76 97)
>>>>> 98 97
>>>>>> 98
The largest element is 98
Now compare with lost ones of the largest element 98. 97 will be the second largest.
nlogn attuazione
public class Test {
public static void main(String...args){
int arr[] = new int[]{1,2,2,3,3,4,9,5, 100 , 101, 1, 2, 1000, 102, 2,2,2};
System.out.println(getMax(arr, 0, 16));
}
public static Holder getMax(int[] arr, int start, int end){
if (start == end)
return new Holder(arr[start], Integer.MIN_VALUE);
else {
int mid = (start + end)/2;
Holder l = getMax(arr, start, mid);
Holder r = getMax(arr, mid + 1, end);
if (l.compareTo(r) > 0)
return new Holder(l.high(), r.high() > l.low() ? r.high() : l.low());
else
return new Holder(r.high(), l.high() > r.low() ? l.high(): r.low());
}
}
static class Holder implements Comparable<Holder> {
private int low, high;
public Holder(int r, int l){low = l; high = r;}
public String toString(){
return String.format("Max: %d, SecMax: %d", high, low);
}
public int compareTo(Holder data){
if (high == data.high)
return 0;
if (high > data.high)
return 1;
else
return -1;
}
public int high(){
return high;
}
public int low(){
return low;
}
}
}
public static int FindSecondLargest(int[] input)
{
Dictionary<int, List<int>> dictWinnerLoser = new Dictionary<int, List<int>>();//Keeps track of loosers with winners
List<int> lstWinners = null;
List<int> lstLoosers = null;
int winner = 0;
int looser = 0;
while (input.Count() > 1)//Runs till we get max in the array
{
lstWinners = new List<int>();//Keeps track of winners of each run, as we have to run with winners of each run till we get one winner
for (int i = 0; i < input.Count() - 1; i += 2)
{
if (input[i] > input[i + 1])
{
winner = input[i];
looser = input[i + 1];
}
else
{
winner = input[i + 1];
looser = input[i];
}
lstWinners.Add(winner);
if (!dictWinnerLoser.ContainsKey(winner))
{
lstLoosers = new List<int>();
lstLoosers.Add(looser);
dictWinnerLoser.Add(winner, lstLoosers);
}
else
{
lstLoosers = dictWinnerLoser[winner];
lstLoosers.Add(looser);
dictWinnerLoser[winner] = lstLoosers;
}
}
input = lstWinners.ToArray();//run the loop again with winners
}
List<int> loosersOfWinner = dictWinnerLoser[input[0]];//Gives all the elemetns who lost to max element of array, input array now has only one element which is actually the max of the array
winner = 0;
for (int i = 0; i < loosersOfWinner.Count(); i++)//Now max in the lossers of winner will give second largest
{
if (winner < loosersOfWinner[i])
{
winner = loosersOfWinner[i];
}
}
return winner;
}
Non ho fatto downvote, ma un po 'di commenti per accompagnare il codice possono aiutarti qui. – LDMJoe
Ho aggiunto alcuni commenti ora, spero che questo possa essere d'aiuto. – SudiptaDas
Il solo voto basso non aiuta, il mio codice soddisfa tutti i requisiti dell'affermazione del problema ed è della complessità temporale desiderata. Si prega di fornire le ragioni del tuo voto negativo. – SudiptaDas
Perché non utilizzare questo algoritmo di hashing per l'array dato [n]? Esegue c * n, dove c è il tempo costante per il controllo e l'hash. E non fa confronti.
int first = 0;
int second = 0;
for(int i = 0; i < n; i++) {
if(array[i] > first) {
second = first;
first = array[i];
}
}
O sono io proprio non capisco la domanda ...
In Python2.7: Il seguente codice funziona in O (log n nlog) per l'ordinamento in più. Qualche ottimizzazione?
def secondLargest(testList):
secondList = []
# Iterate through the list
while(len(testList) > 1):
left = testList[0::2]
right = testList[1::2]
if (len(testList) % 2 == 1):
right.append(0)
myzip = zip(left,right)
mymax = [ max(list(val)) for val in myzip ]
myzip.sort()
secondMax = [x for x in myzip[-1] if x != max(mymax)][0]
if (secondMax != 0):
secondList.append(secondMax)
testList = mymax
return max(secondList)
ho implementato questo algoritmo in Java risposta da @Evgeny Kluev. I confronti totali sono n + log2 (n) -2. C'è anche un buon riferimento: http://users.csc.calpoly.edu/~dekhtyar/349-Spring2010/lectures/lec03.349.pdf. Questo è simile all'algoritmo più votato. Spero che la mia soluzione sia utile. Grazie.
public class op1 {
private static int findSecondRecursive(int n, int[] A){
int[] firstCompared = findMaxTournament(0, n-1, A); //n-1 comparisons;
int[] secondCompared = findMaxTournament(2, firstCompared[0]-1, firstCompared); //log2(n)-1 comparisons.
//Total comparisons: n+log2(n)-2;
return secondCompared[1];
}
private static int[] findMaxTournament(int low, int high, int[] A){
if(low == high){
int[] compared = new int[2];
compared[0] = 2;
compared[1] = A[low];
return compared;
}
int[] compared1 = findMaxTournament(low, (low+high)/2, A);
int[] compared2 = findMaxTournament((low+high)/2+1, high, A);
if(compared1[1] > compared2[1]){
int k = compared1[0] + 1;
int[] newcompared1 = new int[k];
System.arraycopy(compared1, 0, newcompared1, 0, compared1[0]);
newcompared1[0] = k;
newcompared1[k-1] = compared2[1];
return newcompared1;
}
int k = compared2[0] + 1;
int[] newcompared2 = new int[k];
System.arraycopy(compared2, 0, newcompared2, 0, compared2[0]);
newcompared2[0] = k;
newcompared2[k-1] = compared1[1];
return newcompared2;
}
private static void printarray(int[] a){
for(int i:a){
System.out.print(i + " ");
}
System.out.println();
}
public static void main(String[] args) {
//Demo.
System.out.println("Origial array: ");
int[] A = {10,4,5,8,7,2,12,3,1,6,9,11};
printarray(A);
int secondMax = findSecondRecursive(A.length,A);
Arrays.sort(A);
System.out.println("Sorted array(for check use): ");
printarray(A);
System.out.println("Second largest number in A: " + secondMax);
}
}
- 1. Trovare il numero N-esimo più frequente nella matrice
- 2. Trova il rettangolo più grande contenente solo zeri in una matrice binaria N × N
- 3. Il secondo numero più grande
- 4. O-grande complessità del c^n + n * (log n)^2 + (10 * n)^c
- 5. Trova il numero più piccolo e il secondo più piccolo in un array di 8 numeri con solo 9 confronti
- 6. Python - restituisce il numero più grande di N liste
- 7. Quale registro dei tassi di crescita (log * n) e log * (log n) è più veloce?
- 8. O (N log N) Complessità - Simile al lineare?
- 9. trova mediana in O (log n)
- 10. Trova il più grande e il secondo elemento più grande in un intervallo
- 11. Analisi degli algoritmi - Trova numero intero mancante nella matrice ordinata meglio di O (n)
- 12. Come fare qualcosa n volte al secondo?
- 13. Big Oh per (n log n)
- 14. Come si trova il gap più grande in un vettore nel tempo O (n)?
- 15. Trova il prossimo elemento più grande in un array
- 16. Trova più grande area a matrice 2D in C++
- 17. Intersezioni cerchio di calcolo in O ((n + s) log n)
- 18. Qual è la prova di (N-1) + (N-2) + (N-3) + ... + 1 = N * (N-1)/2
- 19. Ricerca di un elemento a log (n)
- 20. Che cos'è O (log * N)?
- 21. n ° il più piccolo numero tra due database di dimensione n ciascuno utilizzando divide e conquista
- 22. numero che appare più di n/3 volte in una matrice
- 23. Come si visualizza la differenza tra O (log n) e O (n log n)?
- 24. git: trova il più grande commit (i)
- 25. più lunga sottostringa che appare n volte
- 26. Trova il valore più grande più piccolo di x in una matrice ordinata
- 27. Ottenere gli indici degli elementi n più grande in una matrice
- 28. Fortran: il più grande e il più piccolo intero
- 29. Cosa significa O (log (log (n)))) - competitivo?
- 30. Pandas secondo più grande del valore
http://stackoverflow.com/questions/251781/how-to-find-the-kth-largest-element-in-an-unsorted-array-of-length-n -in-on – JotaBe
Non penso che possa essere la soluzione. Il motivo è il numero di confronti consentiti. Supponiamo che n = 16 poi finirò per fare 22 confronti in questo modo dato che devo trovare il secondo miglior posto, quindi dovrò sempre memorizzare due numeri per ogni livello e oltre all'ultimo stadio ci saranno sempre due confronti. –
Puoi per favore fammi sapere come posso ottimizzare l'algoritmo di selezione per ridurre al minimo i miei confronti in questo caso? –