14.09.26
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
### 1. Операции над памятью
|
||||
- `load_imm <val>` - прямая загрузка (5 байт)
|
||||
- `load <offset>` - относительная загрузка (3 байта)
|
||||
- `store <offset>` - отночительное сохранение (3 байта)
|
||||
- `store <offset>` - относительное сохранение (3 байта)
|
||||
- `load_addr <addr>` - абсолютная загрузка (5 байт)
|
||||
- `store_addr <addr>` - абсолютное сохранение (5 байт)
|
||||
- `load_acc` - разыменование указателя из `Acc` (1 байт, загружает значение по адресу из аккумулятора `acc <- mem[acc]`)
|
||||
|
||||
@@ -34,4 +34,29 @@
|
||||
- Адрес `0x80` - входной поток - очередь FIFO. При чтении процессором выдает очередной элемент из тестового массива
|
||||
- Адрес `0x84` - выходной поток. Принимает 32-битные слова. Запись любого числа отправляет его в выходной поток
|
||||
## Порядок байтов и адресация
|
||||
Адресация побайтовая, то есть один адрес - один байт. Например, в 32-битной архитектуре чтение по `0x80` захватывает сразу `0x80, 0x81, 0x82, 0x83`. Порядок - `Little Endian`
|
||||
Адресация побайтовая, то есть один адрес - один байт. Например, в 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`
|
||||
@@ -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<Integer> 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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
@@ -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<Integer> 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<Integer> 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;
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -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<Integer> 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;
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -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]]
|
||||
[[Valid Palindrome II]]
|
||||
[[Largest Rectangle In Histogram]]
|
||||
[[Sliding Window Maximum]]
|
||||
|
||||
Reference in New Issue
Block a user