Website Summary Files Commits Branches @commit @diff @stats
path: root / Seminar02 / README.md
diff options
context:
space:
mode:
Commit51d955fbdada4400c8efd504d637b4ece6fcee22 (patch)
Author
 Stoycho Kyosev <stoycho.kk@gmail.com>
2022-10-12 15:42:41 +0300
Committer
 Stoycho Kyosev <stoycho.kk@gmail.com>
2022-10-12 15:42:41 +0300
Filese029d2772c32e4cce968faf6940f1b5bde46f0cc /Seminar02/README.md
Data-structures-and-algorithms-51d955fbdada4400c8efd504d637b4ece6fcee22.tar
Data-structures-and-algorithms-51d955fbdada4400c8efd504d637b4ece6fcee22.tar.gz
Data-structures-and-algorithms-51d955fbdada4400c8efd504d637b4ece6fcee22.zip
Parentfd8930b9c939f3b234b7fe661f329004a931b79c (diff)
add seminar02
1 files changed, 80 insertions, 0 deletions
-rw-r--r--Seminar02/README.md80
diff --git a/Seminar02/README.md b/Seminar02/README.md
new file mode 100644
index 0000000..acb20d6
--- /dev/null
+++ b/Seminar02/README.md
@@ -0,0 +1,80 @@
+# Задачи за стекове 12.10.22
+
+## Задача първа
+Имаме низ състоящ се от английски букви и символа *. Всеки път когато видим * трябва да премахнем символът отляво както и самата звезда.
+Пример:
+* aa* -> "a"
+* erase***** -> ""
+* thi*s i*s exampl*e -> "ths s exampe"
+
+Задачата да се реализира за линейно време с линейна памет.
+## Задача втора
+* Вход: Низ състоящ се от отварящи и затварящи скоби.
+* Изход: Дали скобите в този низ са балансирани
+
+Примери:
+* ((())) -> true
+* ))() -> false
+* )( -> false
+* ()()(()) -> true
+
+## Задача трета
+Обратен полски запис наричаме запис, в който операторите "следват" (са след) числата. Примерно изразът 3 + 4 в обратна полска нотация е 3 4 +. Или изразът 1−2+3 би изглеждал 1 2 −3+. Обикновено първо са дадени числата а след това операциите които извършваме върху тях.
+
+А как би изглеждал израза 1−(2+3). Тук първо трябва да извършим събирането и след това изваждането. Тоест израза се записва като 123+−. Предимството от тази нотация е, че нямаме нужда от скоби, което ускорява сметките. Нашата задача е да напишем функция, която приема валиден стринг в обратна полска нотация и връща пресметнатия резултат.
+
+
+# Монотонни стекове
+Монотонен стек наричаме стек, чиито елементи са монотонно растящи или намаляващи. Монотонните стекове имат приложения върхо много различни и интересни задачи върху масиви. Те може да са монотонно растящи или монотонно намалящи.
+
+```cpp
+void monotonicStackExample(const std::vector<int>& v) {
+ // Нека v = {4, 1, 2, 6, 7, 3}
+ // В стека можем да пазим стойности или индекси в зависимост от задачата.
+ // По името може да познаете какво пазим и какъв е типа на стека.
+ std::stack<int> minMonotonicValues;
+
+ for(int i = 0; i < v.size(); i++) {
+ while(!minMonotonicValues.empty() && minMonotonicValues.top() < v[i]) {
+ minMonotonicValues.pop();
+ }
+ minMonotonicValues.push(v[i]);
+ }
+
+ /*
+ В края на for цикъла при индекс i стека изглежда така:
+ (върха на стека е най - десния елемент)
+ i = 0 : [4]
+ i = 1 : [4, 1]
+ i = 2 : [4, 2]
+ i = 3 : [6]
+ i = 4 : [7]
+ i = 5 : [7, 3]
+ */
+}
+```
+Какво можем да забележим от този пример? Примерно, вярно е, че при i = k максимума на подмасива [0..k - 1] е на дъното на стека.
+
+## Задача четвърта
+Искаме да създадем статична структура от данни построена върху масив, която за константно време по индекс ни връща стойността на първия елемент намиращ се вляво от този индекс и имащ стойност по - голяма или равна от елемента на дадения индекс.
+
+Пример:
+> [1, 4, 3, 8, 12, 7]
+* getMinLeft(0) -> -1 // няма по - голям елемент от 1 в негово ляво
+* getMinLeft(2) -> 4 // 4 е първия елемент по - голям от arr[2] = 3
+* getMinLeft(5) -> 12 // 12 е първия елемент по - голям от arr[5] = 7
+
+## Обяснение на решението:
+От тази задача можем да си направим извода, че точно преди да вкараме елемента в монотонния стек, върха на стека е първия елемент намиращ се вляво от този индекс и имащ стойност по - голяма или равна от елемента на дадения индекс.
+
+Защо това е вярно?
+Нека
+$$
+arr = [a_1 \dots a_k \dots a_m \dots a_n]
+$$
+и нека в цикъла i = m. Твърдя, че ако a_k е първото по - голямо число от a_m то ще бъде задължително на върха на стека след приключване на while цикъла.
+
+
+Ако има други числа на върха на стека, то по предположение те са по - малки от a_m и ще бъдат премахнати.
+
+Ами ако a_k не е в стека? Ако то не е в стека то някое по - голямо от него число, намиращо се между a_k и a_m, го е премахнало. Тоест то не е първото по - голямо число намиращо се вляво.