#5. Generarea tuturor parantezelor
Dându-se un număr n, să se genereze toate combinațiile de paranteze bine-formate. Adică: fiecare paranteză deschisă formează un cuplu cu o paranteză închisă și cuplul începe întotdeauna cu paranteza deschisă.
Exemplu: Input: n = 3
Output: ["((()))","(()())","(())()","()(())","()()()"]
#6. Asezarea unor cutii intr-o stiva
Avem N cutii, fiecare cutie fiind reprezentata in 3 dimensiuni (width, length, height). Ele se pot stivui astfel incat cutia aflata deasupra altei cutii va avea w2 <= w1, l2 <= l1 si h2 <= h1. Nu toate cutiile se pot stivui, dar ele se pot roti astfel incat o inaltime sa devina lungime etc. Care e inaltimea celei mai inalte stive posibile?
Nota: la prima vedere, problema este o variatie la problema Maximum subarray (aflarea sumei maxime a unui subsir dintr-un sir), la care se adauga cateva constrangeri. Am implementat urmatorii pasi:
- transformarea obiectelor-cutie prin rotire astfel incat inaltimea sa fie dimensiunea cu valoarea cea mai mare dintre cele 3D (greedy)
- sortarea cutiilor dupa inaltime, urmata de celelalte doua dimensiuni, descrescator (*)
- aplicarea algoritmului pt Max subarray mentionat anterior, cu adaptarea constrangerilor pentru cutii (programare dinamica)
(*) neasteptat de tricky este sortarea cutiilor. Nu toate cutiile sunt ordonabile, iar un algoritm eficient precum Mergesort greseste pentru anumite cazuri. Asa ca am optat pentru un Bubblesort cu numar maxim de comparatii intre elemente, pentru a forta o relatie de ordonare intre oricare 2 elemente din sirul de cutii. (S-a dovedit si ca doar Bubblesort-ul cu 2 for-uri va functiona corect pentru toate testele!)
Nota: nu e extrem de eficient, dar e corect. Complexitate: timp O(N^2) determinata in principal de Bubblesort, spatiu O(N) pt un array suplimentar.
#7. In cate moduri se pot pune paranteze unei expresii booleene
Se da o expresie formata din valorile 0, 1 (false, true) si operatorii binari &, | si ^. In cate moduri se pot pune paranteze astfel incat evaluarea expresiei sa fie result? Parantezele de genul (( )) nu sunt valide.
Exemplu: countEval('1 & 0 | 1', true) = 2, posibilitatile sunt 1 & (0 | 1) si (1 & 0) | 1.
Rezolvare: cateva observatii:
- cazuri de baza: countEval(Strings.EMPTY, result) = 0 si countEval(str, result) ~ str.equals(result) adica 0 sau 1, cand str are un singur caracter.
- valorile 0 si 1 vor sta intotdeauna pe pozitiile 0, 2, 4, ... n , pe cand operatorii binari vor sta intotdeauna pe pozitiile 1, 3, 5, ... n-1
- asta duce la un for (int i=1; i<str.length(); i+=2) in care sa calculam subproblemele
- daca ne situam pe pozitia unui operator (i), putem calcula recursiv leftCountTrue = countEval(str.substring(0, i), true) si rightCountTrue = countEval(str.substring(i+1), true). Similar si leftCountFalse, rightCountFalse. Toate variabilele ne trebuie pentru ca la un '|', de exemplu, evaluarea uneia din parti poate fi si false, iar rezultatul final sa fie true.
- se calculeaza totalCount = toate modurile posibile de a obtine orice rezultat al evaluarii, care consta din toate modurile de a aranja parantezele in partea stanga * toate modurile de a aranja parantezele in partea dreapta
- totalCount = (leftTrue + leftFalse) * (rightTrue + rightFalse);
- calculam totalCountTrue in functie de operatorul de pe pozitia i:
- '&' --> totalCountTrue = leftCountTrue * rightCountTrue
- '|' --> totalCountTrue = leftCountTrue * rightCountTrue + leftCountTrue * rightCountFalse + leftCountFalse * rightCountTrue;
- '^' --> totalCountTrue = leftCountTrue * rightCountFalse + leftCountFalse * rightCountTrue;
- in functie de rezultatul dorit, solutia subproblemei curente este totalCountTrue sau totalCount - totalCountTrue. Ea se adauga la variabila pentru pastrarea tuturor modurilor.
- if (memo.containsKey(result + str)) return memo.get(result+str);
- memo.put(result+str, countWays);
Niciun comentariu:
Trimiteți un comentariu