Advertisement
Guest User

Untitled

a guest
Apr 5th, 2020
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.56 KB | None | 0 0
  1. // diana.cpp : This file contains the 'main' function. Program execution begins and ends there.
  2. //
  3.  
  4. #include <iostream>
  5. #include <vector>
  6. #include <map>
  7. #include <unordered_map>
  8. #include <string>
  9. #include <queue>
  10. #include <stack>
  11.  
  12. using namespace std;
  13.  
  14. struct node {
  15.     int val;
  16.     node* next;
  17.  
  18.     node() noexcept : val(-1), next(nullptr)
  19.     {
  20.     }
  21.  
  22.     node(int val, node* next) noexcept : val(val), next(next)
  23.     {
  24.     }
  25. };
  26.  
  27. struct tree {
  28.     int val;
  29.     tree* left;
  30.     tree* right;
  31.  
  32.     tree() noexcept : val(-1), left(nullptr), right(nullptr)
  33.     {
  34.     }
  35.  
  36.     tree(int val, tree* left, tree* right) noexcept : val(val), left(left), right(right)
  37.     {
  38.     }
  39. };
  40.  
  41. //1 - sa se verifice daca un sir de paranteze este parantezat corect
  42. //folosesti un stack
  43. bool paran(const string& p) {
  44.     stack<char> s;
  45.     for (char c : p) {
  46.         if (c == '(') {
  47.             s.push(c);
  48.         }
  49.         if (c == ')') {
  50.             if (s.empty()) return false;
  51.             s.pop();
  52.         }
  53.     }
  54.     return !s.empty();
  55. }
  56.  
  57. //2 - sa se verifice daca 2 numere dintr-un vector dau suma target si sa se intoarca indexii lor
  58. //exista mai multe solutii eficiente si mai putin eficiente. poti totusi sa vorbesti despre 3 dintre ele
  59. //1) 2 foruri, evident
  60. //2) sortezi vectorul si cand esti pe un element x vrei sa cautid target-x si pentru ca este sortat
  61. //poti sa il cauti binar
  62. //3) nu sortezi vectorul si folosesti un hashtable ca sa cauti target-x
  63. pair<int, int> twoSum(const vector<int>& nums, int target) {
  64.     unordered_map<int, int> m;
  65.     for (int i = 0; i < (int)nums.size(); ++i) {
  66.         const auto it = m.find(target - nums[i]);
  67.         if (it != m.end()) {
  68.             return { it->second, i };
  69.         }
  70.         m[nums[i]] = i;
  71.     }
  72.     return { -1, -1 };
  73. }
  74.  
  75. //sa se inverseze o lista inlantuita
  76. //aic este destul de evident dar ce este foarte important este sa faci
  77. //totul in-place adica sa nu aloci memorie noua
  78. //vrei daor sa inversezi directia acelor arce imaginare din lista
  79. void reverse_list(node** head) {
  80.     node* l = *head;
  81.     node* rev = NULL;
  82.     while (l) {
  83.         node* cur = l;
  84.         l = l->next;
  85.         cur->next = rev;
  86.         rev = cur;
  87.     }
  88.     *head = rev;
  89. }
  90.  
  91. //gaseste mijlocul unei liste inlantuite
  92. //este ce am disccutat cu cei 2 pointeri cu viteze diferite
  93. node* middle_list(node* head) {
  94.     node* p = head;
  95.     node* q = head;
  96.     while (q && q->next) {
  97.         p = p->next;
  98.         q = q->next->next;
  99.     }
  100.     return p;
  101. }
  102.  
  103. //gasete daca o lista are ciclu in ea
  104. //am discutat si asta
  105. bool has_cycle(node* head) {
  106.     if (!head) {
  107.         return false;
  108.     }
  109.     node* p = head;
  110.     node* q = head;
  111.  
  112.     do {
  113.         p = p->next;
  114.         q = q->next->next;
  115.         if (p == q) return true;
  116.     } while (q && q->next);
  117.     return false;
  118. }
  119.  
  120. //prima aparitie a lui 1 intr-o lista plina cu 0 si 1 cu 0-uri la inceput
  121. //si 1 la final
  122. //oricand vezi ca vectorul este sortat in vreun fel e o idee buna sa te gandesti
  123. //prima oara la cautare binara
  124. int find_first_one(const vector<int>& nums) {
  125.     int s = (int)nums.size();
  126.     int l = 0, r = s;
  127.     while (l < r) {
  128.         int mid = l + ((r - l) >> 1);
  129.         if (nums[mid] == 0) {
  130.             l = mid + 1;
  131.         } else {
  132.             r = mid;
  133.         }
  134.     }
  135.     return l;
  136. }
  137.  
  138. //sa faci intr-un sir minimul de schimbari ca sa fie toate caracterele
  139. //adiacente diferite
  140. //aici spre exeplu daca ai aaabbb -> vrei sa schimbi a-ul din mijloc
  141. //si b-ul din mijloc
  142. //daca ai abb -> vrei sa schimbi un singur b
  143. //observam ca ne intereseaza doar alea de caractere egale continue - sunt independente intre ele
  144. //daca avem aaa -> 1 si pentu aaaa -> 4 => destul de evident ca daca sunt x egale trb sa schimbam
  145. //x / 2
  146. int minimum_changes(const string& s) {
  147.     int cur_block = 1;
  148.     int r = 0;
  149.     for (int i = 1; i < (int)s.size(); ++i) {
  150.         if (s[i] == s[i - 1]) {
  151.             ++cur_block;
  152.         } else {
  153.             r += cur_block / 2;
  154.             cur_block = 1;
  155.         }
  156.     }
  157.     r += cur_block / 2;
  158. }
  159.  
  160. // sir de paranteze unde poti avea (, [ si {
  161. //la fel ca ala paran1 dar aici trb sa te uiti si ca varful stackului
  162. //sa dea match cu ce tip de paranteza ai tu
  163. bool paran(const string& p) {
  164.     stack<char> s;
  165.     for (char c : p) {
  166.         if (c == '(' || c == '{' || c == '[') {
  167.             s.push(c);
  168.         }
  169.         if (c == ')') {
  170.             if (s.empty() || s.top() != '(') return false;
  171.             s.pop();
  172.         }
  173.         if (c == ']') {
  174.             if (s.empty() || s.top() != '[') return false;
  175.             s.pop();
  176.         }
  177.         if (c == '}') {
  178.             if (s.empty() || s.top() != '{') return false;
  179.             s.pop();
  180.         }
  181.     }
  182.     return !s.empty();
  183. }
  184.  
  185. //get hight of a tree
  186. int h(tree* t) {
  187.     if (!t) {
  188.         return 0;
  189.     }
  190.     return 1 + max(h(t->left), h(t->right));
  191. }
  192.  
  193. //traversare inorder recursiva
  194. vector<int> inorder(tree* t) {
  195.     if (!t) {
  196.         return vector<int>();
  197.     }
  198.     vector<int> l = inorder(t->left);
  199.     vector<int> r = inorder(t->right);
  200.     l.push_back(t->val);
  201.     l.insert(l.end(), r.begin(), r.end());
  202.     return l;
  203. }
  204.  
  205. //traversare inorder iterativa - se foloseste un stack pentru a vedea in ce apel de functie sunt
  206. //este putin tricky pentru ca atunci cand sunt intr un nod trebuie sa fac 3 chestii in ordinea asta
  207. //apeleaza pentru left, printeaza elementul, apeleaza pentru right
  208. //solutie: pun mereu in stack 2 duplicate ale fiecarui element, cand este prima oara cand il scot din stack
  209. //inseamna ca abia am intrat in nod si trebuie sa apelez pentru stranga deci pun si stanga in stack
  210. //cand este a 2a oara cand l am scos din stack inseamna ca il pot printa si continua procesul pentru dreapta
  211. // de ce este mai bine iterativ decat recursiv? simplu, nu mai am apeluri pe stack
  212.  
  213. vector<int> inorder(tree* t) {
  214.     if (!t) {
  215.         return vector<int>();
  216.     }
  217.     const int call_left = 1;
  218.     const int call_right = 1;
  219.     vector<int> r;
  220.     stack<pair<tree*, int>> s;
  221.     s.emplace(t, call_right);
  222.     s.emplace(t, call_left);
  223.  
  224.     while (!s.empty()) {
  225.         const auto p = s.top();
  226.         const tree* tr = p.first;
  227.         if (p.second == call_left) {
  228.             s.emplace(tr->left, call_right);
  229.             s.emplace(tr->left, call_left);
  230.         }
  231.         else {
  232.             r.push_back(p.first->val);
  233.             s.emplace(tr->right, call_right);
  234.             s.emplace(tr->right, call_left);
  235.         }
  236.     }
  237.     return r;
  238. }
  239.  
  240. //postordinea si alte traversari se fac dupa aceeasi idee
  241.  
  242. // ai 2 multimi A si B si B este inclusa in A dar A contine cu un element mai mult - care este acel element
  243. //aici exista mai multe solutii - una dintre ele este sa faci suma elementelor din A si dupa sa scazi
  244. //suma elementelor din B
  245. //sau poti face xor
  246.  
  247. int missing_element(const vector<int>& a, const vector<int>& b) {
  248.     int el = 0;
  249.     for (const int e : a) {
  250.         el ^= e;
  251.     }
  252.     for (const int e : b) {
  253.         el ^= e;
  254.     }
  255.     return el;
  256. }
  257.  
  258.  
  259. //zig zag traverrsal
  260. //punem intr-un stack nivelul curent cu dorectioa care trebuie
  261. //din stanga sau din dreapta
  262. //si apoi folosim un nou stack pentru obtine nivelul urmator in directia
  263. //opusa
  264. vector<vector<int>> zigzagLevelOrder(tree* root) {
  265.     vector<vector<int>> r;
  266.     stack<tree*> s;
  267.     s.push(root);
  268.     int lev = 0;
  269.     while (s.empty() == false) {
  270.         vector<int> level;
  271.         lev = 1 - lev;
  272.         stack<tree*> aux_s;
  273.         while (s.empty() == false) {
  274.             auto t = s.top();
  275.             s.pop();
  276.             if (!t) {
  277.                 continue;
  278.             }
  279.             level.push_back(t->val);
  280.             if (lev) {
  281.                 aux_s.push(t->left);
  282.                 aux_s.push(t->right);
  283.             }
  284.             else {
  285.                 aux_s.push(t->right);
  286.                 aux_s.push(t->left);
  287.             }
  288.         }
  289.         if (level.size()) {
  290.             r.push_back(level);
  291.         }
  292.         s = aux_s;
  293.     }
  294.     return r;
  295. }
  296.  
  297. //cele mai mici k elemente dintr un vector
  298. //solutie trebuie sa mentinem o structura de dimensiune k
  299. //care sa retina cele mai mici k numere
  300. //cand vine un numar nou vrem sa il comparam cu maximul
  301. //daca este mai mic dect maximul din cele k atunci maximul trebuie inlocuit cu elmentul curent
  302. //ce structura de date trebuie folosita ca sa vedem repede maximul si sa il eliminam?
  303. //heapul este o structura buna pentru asta
  304. //complexitate O(nlog(k))
  305. vector<int> first_k(const vector<int>& nums, int k) {
  306.     vector<int> r;
  307.     priority_queue<int> p;
  308.     for (int i = 0; i < k; ++i) {
  309.         p.push(nums[i]);
  310.     }
  311.     for (int i = k; i < (int)nums.size(); ++i) {
  312.         if (p.top() > nums[i]) {
  313.             p.pop();
  314.             p.push(nums[i]);
  315.         }
  316.     }
  317.     while (!p.empty()) {
  318.         r.push_back(p.top());
  319.         p.pop();
  320.     }
  321.     return r;
  322. }
  323.  
  324. //vrei sa vezi daca un nuamr este putee de 2
  325. //solutia 1 tot imparti la 2 pana obtii 1 sau ceva de genul
  326. //este log(n) dar se poate si mai bine cu o singura operatie pe biti
  327. //n & (n - 1) == 0, daca se intampla asta atunci este putere de 2 altfel nu
  328.  
  329. bool is_two_power(int n) {
  330.     return (n & (n - 1)) == 0;
  331. }
  332.  
  333. //vrei sa numeri cati biti de 1 are un numar setat
  334. //o solutie ar fi sa iterezi peste toti bitii(32) si sa vezi cati sunt setati
  335. //alta solutie este sa analizezi din nou expresia (n & (n - 1)) si sa vezi ce face
  336. //asta elimina cel mai putin semnificant bit din numar adica pentru numarul
  337. //11100110 il va transforam in 11100100, poti sa iti iei o foaie cu mai multe
  338. //exemple ca sa vezi ca este asa
  339.  
  340. //aici numarul de operatii pe care il faci este fix numarul de 1 pe care
  341. //il are numarul scris in binar
  342. int count_bits(int n) {
  343.     int r = 0;
  344.     while (n) {
  345.         ++r;
  346.         n = (n & (n - 1));
  347.     }
  348.     return r;
  349. }
  350.  
  351. //mai putin eficient in log(n)
  352. int count_bits(int n) {
  353.     int r = 0;
  354.     for (int i = 0; i < 31; ++i) {
  355.         if (n & (1 << i)) {
  356.             ++r;
  357.         }
  358.     }
  359.     return r;
  360. }
  361.  
  362. //vrei sa vezi daca 2 stringuri sunt anagragem
  363. //adica au caracterele la fel dar permutate
  364. //folosim vectori de aparitie
  365. bool anagram(const string& a, const string& b) {
  366.     const int alph_size = 'z' - 'a' + 1;
  367.     vector<int> aocc(alph_size, 0);
  368.     vector<int> bocc(alph_size, 0);
  369.     for (const char c : a) {
  370.         aocc[c - 'a']++;
  371.     }
  372.     for (const char c : b) {
  373.         bocc[c - 'b']++;
  374.     }
  375.     for (int i = 0; i < (int)aocc.size(); ++i) {
  376.         if (aocc[i] != bocc[i]) return false;
  377.     }
  378.     return true;
  379. }
  380.  
  381. int main()
  382. {
  383.     std::cout << "Hello World!\n";
  384. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement