This shows you the differences between two versions of the page.
pa:laboratoare:laborator-00 [2021/03/03 01:44] miruna_elena.banu [De ce PA?] |
pa:laboratoare:laborator-00 [2025/03/06 22:57] (current) darius.neatu [Exercitii] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Laborator 00: Intro to PA ====== | + | ====== Laborator 00: Intro to PA ====== |
- | Responsabili / autori: | + | |
- | * [[neatudarius@gmail.com|Darius-Florentin Neațu (2017-2021)]] | + | |
- | * [[radunichita99@gmail.com | Radu Nichita (2021)]] | + | |
- | * [[cristianolaru99@gmail.com | Cristian Olaru (2021)]] | + | |
- | * [[mirunaelena.banu@gmail.com | Miruna-Elena Banu (2021)]] | + | |
- | * [[maraioana9967@gmail.com | Mara-Ioana Nicolae (2021)]] | + | |
> PA = Proiectarea Algoritmilor | > PA = Proiectarea Algoritmilor | ||
===== De ce PA? ===== | ===== De ce PA? ===== | ||
Line 63: | Line 56: | ||
+ | ===== Debugging ===== | ||
+ | Pe parcursul semestrului, vă poate fi util să știți cum se folosește un debugger pentru a găsi probleme într-un mod rapid. Vă recomandăm articolul [[https://ocw.cs.pub.ro/courses/programare/tutoriale/debugging | PC@Debugging]] pentru a vă reaminti de cum folosim GDB atât din CLI cât și prin intermediul unui IDE. | ||
====== Desfășurare laborator ===== | ====== Desfășurare laborator ===== | ||
În prima săptămână se va clona repo-ul de laborator conform instrucțiunilor de pe pagina [[https://ocw.cs.pub.ro/courses/pa/laboratoare/pa-lab |pa-lab]]. În fiecare săptămână se rulează comanda "git pull" pentru obținerea scheletului actualizat înainte de fiecare laborator. | În prima săptămână se va clona repo-ul de laborator conform instrucțiunilor de pe pagina [[https://ocw.cs.pub.ro/courses/pa/laboratoare/pa-lab |pa-lab]]. În fiecare săptămână se rulează comanda "git pull" pentru obținerea scheletului actualizat înainte de fiecare laborator. | ||
- | |||
- | În acest an, laboratorul valorează **0p**. Acesta se desfășoară sub formă de seminar: asistentul prezintă algoritmii studiați și rezolvă probleme împreună cu studenții. | ||
Secțiunile de **Exerciții ** / **Bonus** / **Extra** reprezintă seturi de probleme grupate pe nivele de dificultate (de la ușor la greu). Recomandăm rezolvarea tuturor exercițiilor propuse, pentru înțelegerea algoritmilor studiați. | Secțiunile de **Exerciții ** / **Bonus** / **Extra** reprezintă seturi de probleme grupate pe nivele de dificultate (de la ușor la greu). Recomandăm rezolvarea tuturor exercițiilor propuse, pentru înțelegerea algoritmilor studiați. | ||
Line 73: | Line 66: | ||
===== Exercitii ===== | ===== Exercitii ===== | ||
- | În lab00 nu există exerciții propriu-zise. | + | |
Task-uri: | Task-uri: | ||
- | * Citiți README de pe pagina principala [[https://github.com/acs-pa/pa-lab | pa-lab]]. | + | * **Task00**: Citiți README de pe pagina principala [[https://github.com/acs-pa/pa-lab | pa-lab]]. Alegeți un limbaj de programare dintre C++ și Java și parcurgeți tutorialul aferent din [[https://github.com/acs-pa/pa-lab/tree/main/skel/lab00 | pa-lab::skel/lab00]]. |
- | * Fiecare trebuie să își aleagă un limbaj de programare și să facă tutorialul aferent din [[https://github.com/acs-pa/pa-lab/tree/main/skel/lab00 | pa-lab::skel/lab00]]. | + | * **Task01**: Se dă un vector cu n elemente și un număr k. Aflați al k-lea cel mai mare număr din vector. |
- | + | * **Restricții**: | |
+ | * $ 1 <= k <= n <= 10^5 $ | ||
+ | * Elementele vectorului au valori cuprinse între 0 și $ 10 ^ 9 $ | ||
+ | <note> | ||
+ | Ca să înțelegem cum ne dorim să procedăm la PA, următoarea problemă este rezolvată. Soluțiile pentru această problemă se pot încărca pe platforma [[https://leetcode.com/problems/kth-largest-element-in-an-array/description/ | Leetcode]]. | ||
+ | </note> | ||
+ | |||
+ | <spoiler Soluția 1> | ||
+ | Putem sorta vectorul crescător și să întoarcem al k-lea element de la finalul vectorului. Complexitate este de $ O(n log n) $. | ||
+ | </spoiler> | ||
+ | |||
+ | <spoiler Soluția 1 implementată în C++> | ||
+ | <code cpp> | ||
+ | class Solution { | ||
+ | public: | ||
+ | int findKthLargest(vector<int>& nums, int k) { | ||
+ | std::sort(nums.begin(), nums.end()); | ||
+ | return nums[nums.size() - k]; | ||
+ | } | ||
+ | }; | ||
+ | </code> | ||
+ | </spoiler> | ||
+ | |||
+ | <spoiler Soluția 1 implementată în Java> | ||
+ | <code java> | ||
+ | class Solution { | ||
+ | public int findKthLargest(int[] nums, int k) { | ||
+ | Arrays.sort(nums); | ||
+ | return nums[nums.length - k]; | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | </spoiler> | ||
+ | |||
+ | <spoiler Soluția 2> | ||
+ | Pentru soluția precedentă, nu ne-am folosit de faptul că $ k < n $, deci s-ar putea obține ceva mai eficient. Trebuie să parcugem măcar o dată vectorul, deci mai puțin de $ O(n)$ nu putem obține. Fix n pași nu putem face, trebuie să îl folosim pe k. Deoarece ne trebuie al k-lea cel mai mare element, intuitiv ar trebui să ținem minte într-o structură de date cele mai mari k elemente din vector. | ||
+ | |||
+ | Ce structură alegem? Dorim să putem insera în ea și să ne zică maximul. Am fi tentați să folosim un max heap. | ||
+ | |||
+ | Când am adăuga un nou element, am dori să îl ștergem pe cel mai mic din structura de date. Prin urmare, am putea să folosim un min heap, în care ne propunem ca la orice moment stocăm cele mai mari k elemente din vector, parcurse până acum. | ||
+ | |||
+ | Astfel: | ||
+ | |||
+ | 1. Se adaugă inițial primele k elemente în heap. | ||
+ | |||
+ | 2. Pentru fiecare din elementele următoarele, dacă acesta este mai mare decât minimul din heap, se șterge minimul și se adaugă elementul curent. Mereu în heap avem k elemente la final de pas în această etapă. | ||
+ | |||
+ | 3. Răspunsul este minimul din heap la finalul parcurgerii. | ||
+ | |||
+ | Complexitate este de $ O(n log k) $, care este mai bună. Implementați și testați pe Leetcode! | ||
+ | |||
+ | </spoiler> | ||
+ | |||
+ | <spoiler Soluția 3> | ||
+ | Hint: Soluția 2 nu este optimă! Se poate și $O(n)$, dar considerăm că este înafara scopului laboratorului 0. | ||
+ | </spoiler> | ||
+ | |||
+ | * **Task02**: Discutați problema [[https://leetcode.com/problems/sliding-window-maximum/| Sliding Window Maximum]] și problema [[https://leetcode.com/problems/longest-substring-without-repeating-characters| Longest Substring without repeating characters]]. Implementați și testați cel puțin o problemă. | ||
+ | |||
+ | * **Task03**: Rezolvați problema [[https://leetcode.com/problems/min-stack/description/| Min Stack]]. |