Задача: 661. Image Smoother
Сложность: easy
Дан целочисленный матрица img размером m x n, представляющая градации серого изображения. Верните изображение после применения сглаживания к каждой его ячейке.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация:
Создайте новую матрицу такого же размера, чтобы сохранить результат сглаживания.
2⃣ Обработка каждой ячейки:
Для каждой ячейки исходной матрицы найдите всех её соседей (включая саму ячейку).
Вычислите среднее значение этих ячеек и сохраните его в соответствующей ячейке результирующей матрицы.
3⃣ Возврат результата:
Верните результирующую матрицу после применения сглаживания ко всем ячейкам.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дан целочисленный матрица img размером m x n, представляющая градации серого изображения. Верните изображение после применения сглаживания к каждой его ячейке.
Пример:
Input: img = [[1,1,1],[1,0,1],[1,1,1]]
Output: [[0,0,0],[0,0,0],[0,0,0]]
Explanation:
For the points (0,0), (0,2), (2,0), (2,2): floor(3/4) = floor(0.75) = 0
For the points (0,1), (1,0), (1,2), (2,1): floor(5/6) = floor(0.83333333) = 0
For the point (1,1): floor(8/9) = floor(0.88888889) = 0
Создайте новую матрицу такого же размера, чтобы сохранить результат сглаживания.
Для каждой ячейки исходной матрицы найдите всех её соседей (включая саму ячейку).
Вычислите среднее значение этих ячеек и сохраните его в соответствующей ячейке результирующей матрицы.
Верните результирующую матрицу после применения сглаживания ко всем ячейкам.
var imageSmoother = function(img) {
let m = img.length, n = img[0].length;
let result = Array.from({ length: m }, () => Array(n).fill(0));
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
let count = 0, total = 0;
for (let ni = Math.max(0, i - 1); ni <= Math.min(m - 1, i + 1); ni++) {
for (let nj = Math.max(0, j - 1); nj <= Math.min(n - 1, j + 1); nj++) {
total += img[ni][nj];
count++;
}
}
result[i][j] = Math.floor(total / count);
}
}
return result;
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 772. Basic Calculator III
Сложность: medium
Реализуйте базовый калькулятор для вычисления простого строкового выражения.
Строка выражения содержит только неотрицательные целые числа, операторы '+', '-', '*', '/' и открывающие '(' и закрывающие скобки ')'. Целочисленное деление должно округляться к нулю.
Предполагается, что данное выражение всегда корректно. Все промежуточные результаты будут находиться в диапазоне [-2^31, 2^31 - 1].
Примечание: нельзя использовать встроенные функции для вычисления строк как математических выражений, такие как eval().
Пример:
👨💻 Алгоритм:
1⃣ Определите вспомогательную функцию evaluate, которая принимает оператор и числовые аргументы. Заметьте, что эта функция идентична той, что представлена в подходе "Basic Calculator II". Инициализируйте несколько переменных: стек для хранения промежуточных результатов, curr для отслеживания текущего числа, которое мы строим, и previousOperator для отслеживания предыдущего оператора. Добавьте в строку s случайный символ, который не будет появляться во входных данных, например "@".
2⃣ Итерация по входным данным. Для каждого символа c: если c является цифрой, добавьте его к curr. В противном случае, если c == '(', мы начинаем вычисление нового изолированного выражения. В этом случае сохраните previousOperator в стек и установите previousOperator = "+".
3⃣ Если c является оператором, то необходимо вычислить значение curr. Используйте функцию evaluate, чтобы применить previousOperator к curr, и добавьте результат в стек. Затем сбросьте curr до нуля и обновите previousOperator = c. Если c == ')', это означает, что мы находимся в конце изолированного выражения и должны полностью его вычислить. Извлекайте из стека до тех пор, пока не достигнете оператора, суммируя все извлеченные числа в curr. Как только достигнете оператора, обновите previousOperator = stack.pop(). Верните сумму всех чисел в стеке.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Реализуйте базовый калькулятор для вычисления простого строкового выражения.
Строка выражения содержит только неотрицательные целые числа, операторы '+', '-', '*', '/' и открывающие '(' и закрывающие скобки ')'. Целочисленное деление должно округляться к нулю.
Предполагается, что данное выражение всегда корректно. Все промежуточные результаты будут находиться в диапазоне [-2^31, 2^31 - 1].
Примечание: нельзя использовать встроенные функции для вычисления строк как математических выражений, такие как eval().
Пример:
Input: s = "1+1"
Output: 2
class Solution {
evaluate(operator, first, second) {
const x = parseInt(first)
const y = parseInt(second)
let res = 0
if (operator === '+') {
res = x
} else if (operator === '-') {
res = -x
} else if (operator === '*') {
res = x * y
} else {
res = Math.trunc(x / y)
}
return res.toString()
}
calculate(s) {
const stack = []
let curr = ""
let previousOperator = '+'
s += "@"
const operators = new Set(["+", "-", "*", "/"])
for (const c of s) {
if (/\d/.test(c)) {
curr += c
} else if (c === '(') {
stack.push(previousOperator)
previousOperator = '+'
} else {
if (previousOperator === '*' || previousOperator === '/') {
stack.push(this.evaluate(previousOperator, stack.pop(), curr))
} else {
stack.push(this.evaluate(previousOperator, curr, "0"))
}
curr = ""
previousOperator = c
if (c === ')') {
let currentTerm = 0
while (!operators.has(stack[stack.length - 1])) {
currentTerm += parseInt(stack.pop())
}
curr = currentTerm.toString()
previousOperator = stack.pop()
}
}
}
let ans = 0
for (const num of stack) {
ans += parseInt(num)
}
return ans
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 977. Squares of a Sorted Array
Сложность: easy
Дан целочисленный массив nums, отсортированный в неубывающем порядке. Верните массив квадратов каждого числа, отсортированный в неубывающем порядке.
Пример:
👨💻 Алгоритм:
1⃣ Создайте массив квадратов каждого элемента.
2⃣ Отсортируйте массив квадратов.
3⃣ Верните отсортированный массив квадратов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дан целочисленный массив nums, отсортированный в неубывающем порядке. Верните массив квадратов каждого числа, отсортированный в неубывающем порядке.
Пример:
Input: nums = [-4,-1,0,3,10]
Output: [0,1,9,16,100]
Explanation: After squaring, the array becomes [16,1,0,9,100].
After sorting, it becomes [0,1,9,16,100].
class Solution {
sortedSquares(nums) {
const ans = nums.map(num => num * num)
ans.sort((a, b) => a - b)
return ans
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Сложность: medium
Задача: 378. Kth Smallest Element in a Sorted Matrix
Дана матрица размером n x n, где каждая строка и каждый столбец отсортированы в порядке возрастания. Верните k-й наименьший элемент в матрице.
Заметьте, что это k-й наименьший элемент в отсортированном порядке, а не k-й уникальный элемент.
Вы должны найти решение с использованием памяти лучше, чем O(n²).
Пример:
👨💻 Алгоритм:
1⃣ Инициализировать мин-кучу H. В нашем решении мы будем рассматривать каждую строку как отдельный список. Поскольку столбцы также отсортированы, мы можем рассматривать каждый столбец как отдельный список.
2⃣ Взять первые элементы из min(N, K) строк, где N представляет количество строк, и добавить каждый из этих элементов в кучу. Важно знать, к какой строке и столбцу принадлежит элемент, чтобы в дальнейшем перемещаться по соответствующему списку.
3⃣ Мин-куча будет содержать тройки информации (значение, строка, столбец). Куча будет упорядочена по значениям, и мы будем использовать номера строк и столбцов для добавления следующего элемента, если текущий элемент будет удален из кучи.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 378. Kth Smallest Element in a Sorted Matrix
Дана матрица размером n x n, где каждая строка и каждый столбец отсортированы в порядке возрастания. Верните k-й наименьший элемент в матрице.
Заметьте, что это k-й наименьший элемент в отсортированном порядке, а не k-й уникальный элемент.
Вы должны найти решение с использованием памяти лучше, чем O(n²).
Пример:
Input: matrix = [[-5]], k = 1
Output: -5
class Solution {
dfs(word, length, visited, dictionary) {
if (length === word.length) {
return true;
}
if (visited[length]) {
return false;
}
visited[length] = true;
for (let i = word.length - (length === 0 ? 1 : 0); i > length; i--) {
if (dictionary.has(word.slice(length, i)) && this.dfs(word, i, visited, dictionary)) {
return true;
}
}
return false;
}
findAllConcatenatedWordsInADict(words) {
const dictionary = new Set(words);
const answer = [];
for (const word of words) {
const visited = Array(word.length).fill(false);
if (this.dfs(word, 0, visited, dictionary)) {
answer.push(word);
}
}
return answer;
}
}
const solution = new Solution();
const words = ["cat", "cats", "catsdogcats", "dog", "dogcatsdog", "hippopotamuses", "rat", "ratcatdogcat"];
console.log(solution.findAllConcatenatedWordsInADict(words));Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 895. Maximum Frequency Stack
Сложность: hard
Разработайте структуру данных, похожую на стек, чтобы заталкивать элементы в стек и вытаскивать из него самый частый элемент. Реализуйте класс FreqStack: FreqStack() строит пустой стек частот. void push(int val) заталкивает целое число val на вершину стека. int pop() удаляет и возвращает самый частый элемент в стеке. Если есть равенство в выборе самого частого элемента, то удаляется и возвращается элемент, который ближе всего к вершине стека.
Пример:
👨💻 Алгоритм:
1⃣ Создать два словаря: freq для хранения частоты каждого элемента и group для хранения стека элементов для каждой частоты.
2⃣ При добавлении элемента увеличивать его частоту в freq и добавлять его в стек соответствующей частоты в group.
3⃣ При извлечении элемента найти максимальную частоту, удалить элемент из стека соответствующей частоты и уменьшить его частоту в freq. Если стек для данной частоты становится пустым, удалить его.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Разработайте структуру данных, похожую на стек, чтобы заталкивать элементы в стек и вытаскивать из него самый частый элемент. Реализуйте класс FreqStack: FreqStack() строит пустой стек частот. void push(int val) заталкивает целое число val на вершину стека. int pop() удаляет и возвращает самый частый элемент в стеке. Если есть равенство в выборе самого частого элемента, то удаляется и возвращается элемент, который ближе всего к вершине стека.
Пример:
Input
["FreqStack", "push", "push", "push", "push", "push", "push", "pop", "pop", "pop", "pop"]
[[], [5], [7], [5], [7], [4], [5], [], [], [], []]
Output
[null, null, null, null, null, null, null, 5, 7, 5, 4]
var FreqStack = function() {
this.freq = new Map();
this.group = new Map();
this.maxfreq = 0;
};
FreqStack.prototype.push = function(val) {
let f = (this.freq.get(val) || 0) + 1;
this.freq.set(val, f);
if (f > this.maxfreq) {
this.maxfreq = f;
this.group.set(f, []);
}
this.group.get(f).push(val);
};
FreqStack.prototype.pop = function() {
let val = this.group.get(this.maxfreq).pop();
this.freq.set(val, this.freq.get(val) - 1);
if (this.group.get(this.maxfreq).length === 0) {
this.maxfreq--;
}
return val;
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 28. Find the Index of the First Occurrence in a String
Сложность: easy
Даны две строки:
Если
Пример:
👨💻 Алгоритм:
1️⃣ Если
2️⃣ Проходим по
3️⃣ Если подстрока равна
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Даны две строки:
haystack и needle. Нужно вернуть индекс первого вхождения строки needle в строку haystack. Если
needle не найдена — вернуть -1.Пример:
Input: haystack = "sadbutsad", needle = "sad"
Output: 0
needle пустая строка — возвращаем 0, так как пустая строка входит в любую строку. haystack от начала до позиции, где ещё может поместиться needle, и на каждой итерации извлекаем подстроку такой же длины. needle, возвращаем текущий индекс. Если не нашли до конца — возвращаем -1.function strStr(haystack, needle) {
if (needle === "") return 0;
for (let i = 0; i <= haystack.length - needle.length; i++) {
let haySlice = haystack.slice(i, i + needle.length);
if (haySlice === needle) {
return i;
}
}
return -1;
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Forwarded from Идущий к IT
🔥 Записал видос "Как за 3 минуты настроить Автоотклики на вакансии HeadHunter" больше не придется заниматься этой унылой рутиной
📺 Видео: https://youtu.be/G_FOwEGPwlw
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1091. Shortest Path in Binary Matrix
Сложность: medium
Дан бинарный матричный массив grid размером n x n. Верните длину самого короткого чистого пути в матрице. Если чистого пути не существует, верните -1.
Чистый путь в бинарной матрице — это путь из верхнего левого угла (т.е. (0, 0)) в нижний правый угол (т.е. (n - 1, n - 1)), такой что:
Все посещенные клетки пути равны 0.
Все соседние клетки пути соединены по 8 направлениям (т.е. они различны и имеют общую сторону или угол).
Длина чистого пути — это количество посещенных клеток этого пути.
Пример:
👨💻 Алгоритм:
1⃣ Проверить, что начальная и конечная клетки открыты (равны 0). Если нет, вернуть -1.
2⃣ Выполнить поиск в ширину (BFS) из начальной клетки, добавляя в очередь соседние клетки, если они открыты и еще не посещены. Обновлять длину пути для каждой клетки.
3⃣ Если достигнута конечная клетка, вернуть длину пути. Если очередь пуста и конечная клетка не достигнута, вернуть -1.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан бинарный матричный массив grid размером n x n. Верните длину самого короткого чистого пути в матрице. Если чистого пути не существует, верните -1.
Чистый путь в бинарной матрице — это путь из верхнего левого угла (т.е. (0, 0)) в нижний правый угол (т.е. (n - 1, n - 1)), такой что:
Все посещенные клетки пути равны 0.
Все соседние клетки пути соединены по 8 направлениям (т.е. они различны и имеют общую сторону или угол).
Длина чистого пути — это количество посещенных клеток этого пути.
Пример:
Input: grid = [[0,1],[1,0]]
Output: 2
var shortestPathBinaryMatrix = function(grid) {
if (grid[0][0] !== 0 || grid[grid.length - 1][grid[0].length - 1] !== 0) {
return -1;
}
const directions = [
[-1, -1], [-1, 0], [-1, 1],
[0, -1], [0, 1],
[1, -1], [1, 0], [1, 1]
];
const queue = [[0, 0]];
grid[0][0] = 1;
while (queue.length > 0) {
const [row, col] = queue.shift();
const distance = grid[row][col];
if (row === grid.length - 1 && col === grid[0].length - 1) {
return distance;
}
for (const [dr, dc] of directions) {
const newRow = row + dr;
const newCol = col + dc;
if (newRow >= 0 && newCol >= 0 && newRow < grid.length && newCol < grid[0].length && grid[newRow][newCol] === 0) {
queue.push([newRow, newCol]);
grid[newRow][newCol] = distance + 1;
}
}
}
return -1;
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 297. Serialize and Deserialize Binary Tree
Сложность: hard
Сериализация — это процесс преобразования структуры данных или объекта в последовательность битов, чтобы их можно было сохранить в файле или буфере памяти или передать по сетевому соединению для последующего восстановления в той же или другой компьютерной среде.
Разработайте алгоритм для сериализации и десериализации бинарного дерева. Нет ограничений на то, как ваш алгоритм сериализации/десериализации должен работать. Вам нужно просто гарантировать, что бинарное дерево может быть сериализовано в строку, и эта строка может быть десериализована в исходную структуру дерева.
Уточнение: формат ввода/вывода такой же, как в LeetCode для сериализации бинарного дерева. Вам не обязательно придерживаться этого формата, так что будьте креативны и придумайте свои подходы.
Пример:
👨💻 Алгоритм:
1⃣ Сериализация дерева:
Используйте рекурсивный обход дерева в порядке root -> left subtree -> right subtree.
Для каждого узла добавляйте его значение в строку сериализации. Если узел пустой, добавляйте "None".
2⃣ Пример:
Начните с корня, узел 1, строка сериализации становится "1,".
Переходите к левому поддереву с корнем 2, строка сериализации становится "1,2,".
Для узла 2, посетите его левый узел 3 ("1,2,3,None,None,") и правый узел 4 ("1,2,3,None,None,4,None,None").
Возвращайтесь к корню 1 и посетите его правое поддерево, узел 5 ("1,2,3,None,None,4,None,None,5,None,None,").
3⃣ Десериализация строки:
Разделите строку на список значений.
Используйте рекурсивную функцию для создания узлов дерева, извлекая значения из списка и восстанавливая структуру дерева. Если значение "None", узел пустой.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Сериализация — это процесс преобразования структуры данных или объекта в последовательность битов, чтобы их можно было сохранить в файле или буфере памяти или передать по сетевому соединению для последующего восстановления в той же или другой компьютерной среде.
Разработайте алгоритм для сериализации и десериализации бинарного дерева. Нет ограничений на то, как ваш алгоритм сериализации/десериализации должен работать. Вам нужно просто гарантировать, что бинарное дерево может быть сериализовано в строку, и эта строка может быть десериализована в исходную структуру дерева.
Уточнение: формат ввода/вывода такой же, как в LeetCode для сериализации бинарного дерева. Вам не обязательно придерживаться этого формата, так что будьте креативны и придумайте свои подходы.
Пример:
Input: root = [1,2,3,null,null,4,5]
Output: [1,2,3,null,null,4,5]
Используйте рекурсивный обход дерева в порядке root -> left subtree -> right subtree.
Для каждого узла добавляйте его значение в строку сериализации. Если узел пустой, добавляйте "None".
Начните с корня, узел 1, строка сериализации становится "1,".
Переходите к левому поддереву с корнем 2, строка сериализации становится "1,2,".
Для узла 2, посетите его левый узел 3 ("1,2,3,None,None,") и правый узел 4 ("1,2,3,None,None,4,None,None").
Возвращайтесь к корню 1 и посетите его правое поддерево, узел 5 ("1,2,3,None,None,4,None,None,5,None,None,").
Разделите строку на список значений.
Используйте рекурсивную функцию для создания узлов дерева, извлекая значения из списка и восстанавливая структуру дерева. Если значение "None", узел пустой.
class TreeNode {
constructor(val = 0, left = null, right = null) {
this.val = val;
this.left = left;
this.right = right;
}
}
class Codec {
rserialize(root, str) {
if (root === null) {
str.push("null");
} else {
str.push(String(root.val));
this.rserialize(root.left, str);
this.rserialize(root.right, str);
}
}
serialize(root) {
const str = [];
this.rserialize(root, str);
return str.join(",");
}
rdeserialize(data) {
if (data[0] === "null") {
data.shift();
return null;
}
const root = new TreeNode(Number(data.shift()));
root.left = this.rdeserialize(data);
root.right = this.rdeserialize(data);
return root;
}
deserialize(data) {
const dataArray = data.split(",");
return this.rdeserialize(dataArray);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1
Задача: 771. Jewels and Stones
Сложность: medium
Вам даны строки jewels, представляющие типы камней, которые являются драгоценностями, и stones, представляющие камни, которые у вас есть. Каждый символ в stones является типом камня, который у вас есть. Вы хотите узнать, сколько из камней, которые у вас есть, также являются драгоценностями.
Буквы чувствительны к регистру, поэтому "a" считается другим типом камня, чем "A".
Пример:
👨💻 Алгоритм:
1⃣ Создайте множество из строки jewels для быстрой проверки, является ли камень драгоценностью. Это позволит эффективно проверять принадлежность каждого камня к драгоценностям.
2⃣ Инициализируйте счетчик для подсчета количества камней, которые являются драгоценностями. Пройдите по каждому символу в строке stones и проверьте, содержится ли этот символ в множестве jewels.
3⃣ Если символ содержится в множестве, увеличьте счетчик. В конце верните значение счетчика, которое будет количеством камней, являющихся драгоценностями.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам даны строки jewels, представляющие типы камней, которые являются драгоценностями, и stones, представляющие камни, которые у вас есть. Каждый символ в stones является типом камня, который у вас есть. Вы хотите узнать, сколько из камней, которые у вас есть, также являются драгоценностями.
Буквы чувствительны к регистру, поэтому "a" считается другим типом камня, чем "A".
Пример:
Input: jewels = "aA", stones = "aAAbbbb"
Output: 3
class Solution {
numJewelsInStones(J, S) {
let ans = 0
for (const s of S) {
for (const j of J) {
if (j === s) {
ans++
break
}
}
}
return ans
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 111. Minimum Depth of Binary Tree
Сложность: easy
Дано бинарное дерево, найдите его минимальную глубину.
Минимальная глубина - это количество узлов вдоль самого короткого пути от корневого узла до ближайшего листового узла.
Пример:
👨💻 Алгоритм:
1️⃣ Мы будем использовать метод обхода в глубину (dfs) с корнем в качестве аргумента.
Базовое условие рекурсии: это для узла NULL, в этом случае мы должны вернуть 0.
2️⃣ Если левый ребенок корня является NULL: тогда мы должны вернуть 1 + минимальную глубину для правого ребенка корневого узла, что равно 1 + dfs(root.right).
3️⃣ Если правый ребенок корня является NULL: тогда мы должны вернуть 1 + минимальную глубину для левого ребенка корневого узла, что равно 1 + dfs(root.left). Если оба ребенка не являются NULL, тогда вернуть 1 + min(dfs(root.left), dfs(root.right)).
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дано бинарное дерево, найдите его минимальную глубину.
Минимальная глубина - это количество узлов вдоль самого короткого пути от корневого узла до ближайшего листового узла.
Пример:
Input: root = [3,9,20,null,null,15,7]
Output: 2
Базовое условие рекурсии: это для узла NULL, в этом случае мы должны вернуть 0.
var minDepth = function (root) {
function dfs(root) {
if (root === null) {
return 0;
}
if (root.left === null) {
return 1 + dfs(root.right);
} else if (root.right === null) {
return 1 + dfs(root.left);
}
return 1 + Math.min(dfs(root.left), dfs(root.right));
}
return dfs(root);
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 851. Loud and Rich
Сложность: medium
Есть группа из n человек, пронумерованных от 0 до n - 1, где у каждого человека разное количество денег и разный уровень спокойствия.
Вам дан массив richer, где richer[i] = [ai, bi] указывает на то, что ai имеет больше денег, чем bi, и целочисленный массив quiet, где quiet[i] — это уровень спокойствия i-го человека. Все данные в richer логически корректны (т.е. данные не приведут к ситуации, где x богаче y и y богаче x одновременно).
Верните целочисленный массив answer, где answer[x] = y, если y — это самый спокойный человек (то есть человек y с наименьшим значением quiet[y]) среди всех людей, которые однозначно имеют столько же или больше денег, чем человек x.
Пример:
👨💻 Алгоритм:
1⃣ Постройте граф, описанный выше, и пусть dfs(person) будет самым спокойным человеком в поддереве person. Обратите внимание, что из-за логической последовательности утверждений граф должен быть DAG — ориентированным графом без циклов.
2⃣ Теперь dfs(person) — это либо сам person, либо min(dfs(child) для каждого child из person). То есть, самый спокойный человек в поддереве — это либо сам person, либо самый спокойный человек в каком-то поддереве потомка person.
3⃣ Мы можем кэшировать значения dfs(person) в answer[person], выполняя обход графа в пост-обходе. Таким образом, мы не повторяем работу. Этот метод уменьшает квадратичное время выполнения алгоритма до линейного.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Есть группа из n человек, пронумерованных от 0 до n - 1, где у каждого человека разное количество денег и разный уровень спокойствия.
Вам дан массив richer, где richer[i] = [ai, bi] указывает на то, что ai имеет больше денег, чем bi, и целочисленный массив quiet, где quiet[i] — это уровень спокойствия i-го человека. Все данные в richer логически корректны (т.е. данные не приведут к ситуации, где x богаче y и y богаче x одновременно).
Верните целочисленный массив answer, где answer[x] = y, если y — это самый спокойный человек (то есть человек y с наименьшим значением quiet[y]) среди всех людей, которые однозначно имеют столько же или больше денег, чем человек x.
Пример:
Input: richer = [[1,0],[2,1],[3,1],[3,7],[4,3],[5,3],[6,3]], quiet = [3,2,5,4,6,1,7,0]
Output: [5,5,2,5,4,5,6,7]
Explanation:
answer[0] = 5.
Person 5 has more money than 3, which has more money than 1, which has more money than 0.
The only person who is quieter (has lower quiet[x]) is person 7, but it is not clear if they have more money than person 0.
answer[7] = 7.
Among all people that definitely have equal to or more money than person 7 (which could be persons 3, 4, 5, 6, or 7), the person who is the quietest (has lower quiet[x]) is person 7.
The other answers can be filled out with similar reasoning.
var loudAndRich = function(richer, quiet) {
let N = quiet.length;
let graph = Array.from({ length: N }, () => []);
let answer = Array(N).fill(-1);
for (let [u, v] of richer) {
graph[v].push(u);
}
let dfs = function(node) {
if (answer[node] === -1) {
answer[node] = node;
for (let child of graph[node]) {
let cand = dfs(child);
if (quiet[cand] < quiet[answer[node]]) {
answer[node] = cand;
}
}
}
return answer[node];
};
for (let node = 0; node < N; node++) {
dfs(node);
}
return answer;
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM