From 00b700a410b48ac227eedf8f3bd45d6407ea6f19 Mon Sep 17 00:00:00 2001 From: roma-dxunvrs Date: Mon, 14 Sep 2026 20:07:06 +0300 Subject: [PATCH] 14.09.26 --- Computer Science/Архитектуры/ACC32.md | 2 +- .../Архитектуры/Платформа Wrench.md | 27 +++++++- .../LeetCode/Largest Rectangle In Histogram.md | 47 ++++++++++++++ АиСД/Задачи/LeetCode/Maximal Rectangle.md | 65 +++++++++++++++++++ .../Задачи/LeetCode/Sliding Window Maximum.md | 33 ++++++++++ АиСД/Методы/Монотонная очередь.md | 0 АиСД/Список задач.md | 6 +- 7 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 АиСД/Задачи/LeetCode/Largest Rectangle In Histogram.md create mode 100644 АиСД/Задачи/LeetCode/Maximal Rectangle.md create mode 100644 АиСД/Задачи/LeetCode/Sliding Window Maximum.md create mode 100644 АиСД/Методы/Монотонная очередь.md diff --git a/Computer Science/Архитектуры/ACC32.md b/Computer Science/Архитектуры/ACC32.md index d76d000..82f82d1 100644 --- a/Computer Science/Архитектуры/ACC32.md +++ b/Computer Science/Архитектуры/ACC32.md @@ -21,7 +21,7 @@ ### 1. Операции над памятью - `load_imm ` - прямая загрузка (5 байт) - `load ` - относительная загрузка (3 байта) -- `store ` - отночительное сохранение (3 байта) +- `store ` - относительное сохранение (3 байта) - `load_addr ` - абсолютная загрузка (5 байт) - `store_addr ` - абсолютное сохранение (5 байт) - `load_acc` - разыменование указателя из `Acc` (1 байт, загружает значение по адресу из аккумулятора `acc <- mem[acc]`) diff --git a/Computer Science/Архитектуры/Платформа Wrench.md b/Computer Science/Архитектуры/Платформа Wrench.md index 7fd9f21..c553faf 100644 --- a/Computer Science/Архитектуры/Платформа Wrench.md +++ b/Computer Science/Архитектуры/Платформа Wrench.md @@ -34,4 +34,29 @@ - Адрес `0x80` - входной поток - очередь FIFO. При чтении процессором выдает очередной элемент из тестового массива - Адрес `0x84` - выходной поток. Принимает 32-битные слова. Запись любого числа отправляет его в выходной поток ## Порядок байтов и адресация -Адресация побайтовая, то есть один адрес - один байт. Например, в 32-битной архитектуре чтение по `0x80` захватывает сразу `0x80, 0x81, 0x82, 0x83`. Порядок - `Little Endian` \ No newline at end of file +Адресация побайтовая, то есть один адрес - один байт. Например, в 32-битной архитектуре чтение по `0x80` захватывает сразу `0x80, 0x81, 0x82, 0x83`. Порядок - `Little Endian` +## Крайние случаи +### Запись во входной порт (0x80) +- `load_imm 42` $\to$ `store_addr 0x80` +- Программа не упала, продолжила работу. Данные исчезли навсегда +- Контроллер порта `0x80` работает только на чтение +### Чтение из выходного порта (0x84) +- Попытались сделать `load_addr 0x84` (или `load_acc` по этому адресу) +- Аварийное завершение `ERROR: input is depleted` по адресу `132` (`0x84`) +- Порт `0x84` — это write-only устройство. У него нет входящей очереди (FIFO), из которой процессор мог бы прочитать байт +### Исполнение кода из порта ввода (JMP 0x80) +- jmp 0x80` +- Аварийное завершение `ERROR: instruction in memory corrupted` +- `PC` выставил адрес `0x80`. Процессор забрал из очереди ввода пользовательский байт (например, букву `'H'` = 72) и попытался декодировать его как машинную команду (Opcode). Команды с таким кодом нет +### Размещение данных прямо в портах (`.org 0x80`) +- Написали `.org 0x80`, положили `.word 42`, а следом секцию `.text` с командой `halt` +- Аварийное завершение при старте: `ERROR: iomemory[132]: instruction corrupted` +- Данные `.word 42` (4 байта) заняли адреса `0x80, 0x81, 0x82, 0x83`. +- Код программы (`halt`) "перелился" в следующую свободную ячейку — `0x84` (132) +- Процессор попытался стартовать с адреса `0x84` (считая его началом `.text`) +- Но `0x84` - это порт только для записи! Процессор не смог прочитать оттуда код и умер при старте +### Несколько `.org` +- Ошибка компилятора `multiple .org directives not allowed` +- В одной секции - один `.org` (один в `.text`, один в `.data`) +### Чтение из пустого ввода +- `ERROR: memory access error: input is depleted` \ No newline at end of file diff --git a/АиСД/Задачи/LeetCode/Largest Rectangle In Histogram.md b/АиСД/Задачи/LeetCode/Largest Rectangle In Histogram.md new file mode 100644 index 0000000..e942f36 --- /dev/null +++ b/АиСД/Задачи/LeetCode/Largest Rectangle In Histogram.md @@ -0,0 +1,47 @@ +Leetcode #84 | #Hard | [[Монотонный стек]] | [[Математика]] +## Идея +Для каждого прямоугольника нам надо найти слева и справа соседей, до которых можно растянуть текущий прямоугольник (например, высота 7, мы находим соседей, пока они >=7). Это можно сделать либо через двойной цикл за квадратичную сложность, либо через монотонный стек. Идем по высотам, если стек пуст - просто ложим. Если текущая высота больше либо равна последней высоте из стека, то пушим ее в стек (можно растянуть), если меньше, то запускаем цикл. Пока текущая высота меньше чем высота на вершине стека, то для вершины стека мы нашли правую границу, а левая - лежит строго под этой высотой в стеке - в силу монотонного стека. Высота равна высоте с вершины стека, ширина `i-stack.peek()-1`, либо `i` (если стек пустой) - здесь `stack.peek()` это высота левой границы. Дальше обновялем результат, после цикла пушим в стек. В конце могли остаться столбцы, для которых не нашлось правых границ. Просто запустим цикл с аналогичными действиями, но только правая граница `heights.length-stack.peek()-1`, либо `heights.length` +## [[Big-O]] +- Время ```O(N)``` +- Память ```O(N)``` +## Код +```Java +class Solution { + public int largestRectangleArea(int[] heights) { + Deque stack = new ArrayDeque<>(); + int res = 0; + + for (int i = 0; i < heights.length; i++) { + while (stack.size() > 0 && heights[i] < heights[stack.peek()]) { + int height = heights[stack.pop()]; + int weight; + + if (stack.size() == 0) { + weight = i; + } else { + weight = i-stack.peek()-1; + } + + res = Math.max(res, height*weight); + } + stack.push(i); + } + + while (stack.size() > 0) { + int height = heights[stack.pop()]; + int weight; + + if (stack.size() == 0) { + weight = heights.length; + } else { + weight = heights.length-stack.peek()-1; + } + + res = Math.max(res, height*weight); + } + + return res; + } +} + +``` \ No newline at end of file diff --git a/АиСД/Задачи/LeetCode/Maximal Rectangle.md b/АиСД/Задачи/LeetCode/Maximal Rectangle.md new file mode 100644 index 0000000..23d6a06 --- /dev/null +++ b/АиСД/Задачи/LeetCode/Maximal Rectangle.md @@ -0,0 +1,65 @@ +Leetcode #85 | #Hard | [[Монотонный стек]] | [[Матрица]] +## Идея +Продолжение [[Largest Rectangle In Histogram]], но эту гистограмму надо построить. Заводим массив высот, идем по строкам. Для каждой строки обновляем массив - если в столбце 0, то ставим 0, если в столбце 1, то инкрементируем эту высоту в нашем массиве. Теперь вызываем метод из прошлой задачи на текущее состояние массива высот. +## [[Big-O]] +- Время ```O(NM)``` +- Память ```O(M)``` +N - кол-во строк, M - кол-во столбцов +## Код +```Java +class Solution { + public int maximalRectangle(char[][] matrix) { + Deque stack = new ArrayDeque<>(); + int[] heights = new int[matrix[0].length]; + int res = 0; + + for (int r = 0; r < matrix.length; r++) { + for (int c = 0; c < matrix[0].length; c++) { + if (matrix[r][c] == '0') { + heights[c] = 0; + } else { + heights[c] += 1; + } + } + res = Math.max(res, getLargestRectangle(heights, stack)); + } + return res; + } + + int getLargestRectangle(int[] heights, Deque stack) { + int res = 0; + stack.clear(); + + for (int i = 0; i < heights.length; i++) { + while (stack.size() > 0 && heights[i] < heights[stack.peek()]) { + int height = heights[stack.pop()]; + int weight; + + if (stack.size() == 0) { + weight = i; + } else { + weight = i-stack.peek()-1; + } + + res = Math.max(res, height*weight); + } + stack.push(i); + } + + while (stack.size() > 0) { + int height = heights[stack.pop()]; + int weight; + + if (stack.size() == 0) { + weight = heights.length; + } else { + weight = heights.length-stack.peek()-1; + } + + res = Math.max(res, height*weight); + } + + return res; + } +} +``` \ No newline at end of file diff --git a/АиСД/Задачи/LeetCode/Sliding Window Maximum.md b/АиСД/Задачи/LeetCode/Sliding Window Maximum.md new file mode 100644 index 0000000..3e3d955 --- /dev/null +++ b/АиСД/Задачи/LeetCode/Sliding Window Maximum.md @@ -0,0 +1,33 @@ +Leetcode #239 | #Hard | [[Монотонный стек]] | [[Монотонная очередь]] | [[Указатель на запись]] +## Идея +Заводим деку для поддержания максимума. Идем по массиву, убираем элементы из деки, пока текущий больше. Кладем текущий в деку. Дальше избавляемся от "протухших" чисел в начале деки. Такие действия гарантируют, что в начале деки всегда лежит наибольший элемент текущего окна, добавляем его в ответ, если конечно окно уже нормального размера. +## [[Big-O]] +- Время ```O(N)``` +- Память ```O(N)``` +## Код +```Java +class Solution { + public int[] maxSlidingWindow(int[] nums, int k) { + int[] res = new int[nums.length-k+1]; + int write = 0; + Deque deque = new ArrayDeque<>(); + + for (int r = 0; r < nums.length; r++) { + while (deque.size() > 0 && nums[r] > nums[deque.peekLast()]) { + deque.pollLast(); + } + deque.offerLast(r); + + while (r-deque.peekFirst() >= k) { + deque.pollFirst(); + } + + if (r+1 >= k) { + res[write++] = nums[deque.peekFirst()]; + } + } + + return res; + } +} +``` \ No newline at end of file diff --git a/АиСД/Методы/Монотонная очередь.md b/АиСД/Методы/Монотонная очередь.md new file mode 100644 index 0000000..e69de29 diff --git a/АиСД/Список задач.md b/АиСД/Список задач.md index a1093a0..1703609 100644 --- a/АиСД/Список задач.md +++ b/АиСД/Список задач.md @@ -52,7 +52,7 @@ [[Max Stack]] [[Lowest Common Ancestor of a Binary Tree III]] [[Longest Substring with At Most Two Distinct Characters]] -Maximal Rectangle +[[Maximal Rectangle]] [[Search in Rotated Sorted Array]] [[Two Sum II – Input Array Is Sorted]] [[Remove Duplicates from Sorted Array]] @@ -73,4 +73,6 @@ Maximal Rectangle [[Best Time to Buy and Sell Stock]] [[Best Time to Buy and Sell Stock II]] [[Implement Trie (Prefix Tree)]] -[[Valid Palindrome II]] \ No newline at end of file +[[Valid Palindrome II]] +[[Largest Rectangle In Histogram]] +[[Sliding Window Maximum]]