Zadanko z listami

0

Na wejściu mamy listę łączoną wraz z dodatkowymi wskaźnikami. Dokładniej wskaźnik next do kolejnego węzła i wskaźnik rand do losowego, ale ustalonego węzła. Naszym zadaniem jest skopiowanie tej listy do nowego obszaru pamięci, tak aby zachować strukturę. Czyli wskaźnik rand ma dalej wskazywać na element o tej samej odległości od początku, gdzie odległość to ilość przejść po wskaźnikach next potrzebna, aby dojść.

Warunki:

  • złożoność obliczeniowa liniowa,
  • stała ilość dodatkowej pamięci (tzn poza tą kopią),
0

No więc trzeba najpierw zmodyfikować pierwotną listę a potem ją odtworzyć.
Najpierw tworzymy sobie kopię listy o takiej samej liczbie elementów z poprawnie ustawionymi wskaźnikami next.
Potem w nowej liście ustawiamy wskaźniki rand na odpowiadające w kolejności elementy ze starej listy.
Elementom ze starej listy wskaźniki next modyfikujemy na odpowiadające w kolejności elementy nowej listy.
Z taką strukturą elegancko updatujemy wskaźniki rand nowej listy i od razu odtwarzamy wskaźniki next starej listy.
Łatwiej narysować niż opisać.

Jeżeli to jakieś zadanie z rekrutacji to całkiem kurewskie. Jeżeli zgadłem to napisz co to za firma.

0

A takie cos:

a) pierwsza iteracja: robimy prosta kopie oryginalnej listy, przypisujac odpowiednio next kopiowanym wezlom, rand pozostawiajac pusty; dodatkowo, budujemy 2 struktury:

  • pierwsza, 'identity hash map', gdzie kluczem jest wezel z oryginalnej listy, a wartoscia jego kolejnosc / indeks w liscie
  • druga to tablica o wielkosci listy, gdzie kazdemu indeksowi przypisujemy wezel ktory na tej pozycji lezy w nowej liscie. Robimy to po to aby miec tymczasowy 'random access' O(1) w liscie laczonej.

b) druga iteracja: jednoczesnie iterujemy po obu listach, zmieniajac synchronicznie aktualnie przetwarzane elementy z obu list. Z oryginalnej listy bierzemy dla kazdego elementu jego element rand, wyszukujemy go w tej 'pierwszej' mapie i mamy jego indeks w liscie. Teraz z 'drugiej' tablicy za pomoca tego indeksu bierzemy wezel (czas O(1), zamiast latac po liscie i zliczac ciagle, co byloby katastrofa w Big Oh), ktory bedzie wezlem rand w nowej liscie, i go ustawiamy jako rand dla aktualnego elementu kopii w danej iteracji.

Wydaje mi sie ze to bedzie dzialac. Roznice z pierwsza odpowiedzia:
a) dwukrotnie wieksze zuzycie pamieci (dodatkowa mapa oraz tablica), ale nadal stale bo zalezne tylko od ilosci wezlow oryginalnej listy (zdaje mi sie, chociaz specem nie jestem, prosze o sprostowanie jesli sie myle)
b) oryginalna lista nie ulega zniszczeniu, pozostaje nie zmieniona - nie wiem czy to ma jakiekolwiek znaczenie, w zadaniu nie ma o tym slowa, ale wydaje mi sie ze mogloby to byc pomocne, i poza tym chcialem sprobowac wlasnie zrobic cos co nie niszczy oryginalu

Prosze o uwagi ;d

0

Ups, i nie doczytalem pierwszej odpowiedzi, tam przeciez tez sie nie psuje listy. Wiec rozwiazanie troche bardziej skomplikowane, ale duzo wydajniejsze. Poklony ;d

0
  • pierwsza, 'identity hash map', gdzie kluczem jest wezel z oryginalnej listy, a wartoscia jego kolejnosc / indeks w liscie

Łamiesz założenie o stałej pamięci dodatkowej.

0

A mozesz rozwinac? Wydaje mi sie ze jest stala, tyle ze potrzeba jej wiecej niz w Twoim rozwiazaniu, ale widac sie myle. Mozesz mi wytlumaczyc?

0

No przecież hash mapa w której trzymasz n elementów listy, ma złożoność pamięciową O(n) a nie O(1).

0

No ale ta dodatkowa lista ma rowniez zlozonosc pamieciowa O(n). Jak mam algorytm ktory 2 razy leci liste liniowo (zreszta Twoj tak wlasnie robi), to ma zlozonosc czasowa O(n), czyli jak mam zuzycie pamieci O(n) dwukrotnie, to to tez jest O(n)?
Czy mam interpretowac:
<quote>

  • stała ilość dodatkowej pamięci (tzn poza tą kopią),
    <quote>
    ze poza ta kopia listy nie moge nic stworzyc, ewentualnie cos co nie jest zalezne od n?

Prosze nie denerwuj sie, nie atakuje Cie ani nic, zakladam ze masz racje a ja sie myle bo malo umiem, ale chcialbym sie nauczyc, dlatego prosze o wyjasnienia.

0

ismail:
No tu chodzi o stałą ilość pamięci dodatkowej, czyli kilka zmiennych (oględnie mówiąc). Dla przykładu algorytmy sortujące wymagają zwykle O(1) pamięci dodatkowej (np HeapSort, InsertionSort, BubbleSort) czy O(log n) pamięci dodatkowej (QuickSort) i jest ważne, aby więcej pamięci dodatkowej nie zabierały. Tak samo tutaj jest ważne, aby algorytm nie zabierał więcej niż O(1) pamięci dodatkowej.

0

Dzieki, zrozumiano.

1 użytkowników online, w tym zalogowanych: 0, gości: 1