C/C++ | LeetCode
الذهاب إلى القناة على Telegram
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @sendme_ads
إظهار المزيد3 207
المشتركون
-124 ساعات
-77 أيام
-2230 أيام
أرشيف المشاركات
3 207
Задача: 1514. Path with Maximum Probability
Сложность: medium
Вам дан неориентированный взвешенный граф из n узлов (индексация с нуля), представленный списком ребер, где edges[i] = [a, b] является неориентированным ребром, соединяющим узлы a и b с вероятностью успешного прохождения этого ребра succProb[i].
Даны два узла start и end, найдите путь с максимальной вероятностью успеха, чтобы перейти от start к end, и верните его вероятность успеха.
Если пути от start до end не существует, верните 0. Ваш ответ будет принят, если он отличается от правильного ответа не более чем на 1e-5.
Пример:
Input: n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.2], start = 0, end = 2
Output: 0.25000
Explanation: There are two paths from start to end, one having a probability of success = 0.2 and the other has 0.5 * 0.5 = 0.25.
👨💻 Алгоритм:
1⃣Инициализируйте массив maxProb как максимальную вероятность достижения каждого узла из начального узла, установите maxProb[start] равным 1.
2⃣Расслабьте все ребра: для каждого ребра (u, v), если найдена более высокая вероятность достижения u через это ребро, обновите max_prob[u] как max_prob[u] = max_prob[v] * path_prob. Если найдена более высокая вероятность достижения v через это ребро, обновите max_prob[v].
3⃣Если нам не удается обновить какой-либо узел с более высокой вероятностью, мы можем остановить итерацию, перейдя к шагу 4. В противном случае повторяйте шаг 2, пока все ребра не будут расслаблены n - 1 раз.
Верните max_prob[end].
😎 Решение:
class Solution {
public:
double maxProbability(int n, vector<vector<int>>& edges, vector<double>& succProb, int start, int end) {
vector<double> maxProb(n, 0.0);
maxProb[start] = 1.0;
for (int i = 0; i < n - 1; i++) {
bool hasUpdate = false;
for (int j = 0; j < edges.size(); j++) {
int u = edges[j][0];
int v = edges[j][1];
double pathProb = succProb[j];
if (maxProb[u] * pathProb > maxProb[v]) {
maxProb[v] = maxProb[u] * pathProb;
hasUpdate = true;
}
if (maxProb[v] * pathProb > maxProb[u]) {
maxProb[u] = maxProb[v] * pathProb;
hasUpdate = true;
}
}
if (!hasUpdate) {
break;
}
}
return maxProb[end];
}
};
Ставь 👍 и забирай 📚 Базу знаний3 207
Задача: 666. Path Sum IV
Сложность: medium
Если глубина дерева меньше 5, то это дерево можно представить в виде массива трехзначных чисел. Для каждого числа в этом массиве:
Сотни представляют глубину d этого узла, где 1 <= d <= 4.
Десятки представляют позицию p этого узла на уровне, которому он принадлежит, где 1 <= p <= 8. Позиция соответствует позиции в полном бинарном дереве.
Единицы представляют значение v этого узла, где 0 <= v <= 9.
Дан массив возрастающих трехзначных чисел nums, представляющих бинарное дерево с глубиной меньше 5. Верните сумму всех путей от корня к листьям.
Гарантируется, что данный массив представляет собой валидное связанное бинарное дерево.
Пример:
Input: nums = [113,215,221] Output: 12 Explanation: The tree that the list represents is shown. The path sum is (3 + 5) + (3 + 1) = 12.👨💻 Алгоритм: 1⃣Создание структуры дерева: Пройдите по массиву nums и для каждого элемента создайте узел дерева. Сохраните узлы в словаре для удобного доступа по их позиции. 2⃣Связывание узлов: Пройдите по массиву и свяжите узлы друг с другом, исходя из их позиции и глубины. Найдите левого и правого ребенка для каждого узла и установите соответствующие связи. 3⃣Подсчет суммы путей: Выполните обход дерева (например, используя DFS) и подсчитайте сумму всех путей от корня к листьям. 😎 Решение:
class Solution {
public:
int pathSum(vector<int>& nums) {
unordered_map<int, int> tree;
for (int num : nums) {
int depth = num / 100;
int pos = (num / 10) % 10;
int val = num % 10;
tree[depth * 10 + pos] = val;
}
return dfs(tree, 1, 1, 0);
}
private:
int dfs(unordered_map<int, int>& tree, int depth, int pos, int currentSum) {
int key = depth * 10 + pos;
if (!tree.count(key)) {
return 0;
}
currentSum += tree[key];
int leftChild = (depth + 1) * 10 + 2 * pos - 1;
int rightChild = (depth + 1) * 10 + 2 * pos;
if (!tree.count(leftChild) && !tree.count(rightChild)) {
return currentSum;
}
return dfs(tree, depth + 1, 2 * pos - 1, currentSum) + dfs(tree, depth + 1, 2 * pos, currentSum);
}
};
Ставь 👍 и забирай 📚 Базу знаний3 207
Задача: 844. Backspace String Compare
Сложность: easy
Даны две строки s и t, верните true, если они равны после ввода в пустые текстовые редакторы. Символ '#' означает клавишу backspace.
Обратите внимание, что после нажатия backspace на пустом тексте, текст останется пустым.
Пример:
Input: s = "ab#c", t = "ad#c" Output: true Explanation: Both s and t become "ac".👨💻 Алгоритм: 1⃣Пройдите по строкам s и t с конца, учитывая символы '#' как backspace и пропуская соответствующие символы. 2⃣Сравнивайте текущие символы из обеих строк, пропуская символы, которые должны быть удалены. 3⃣Если все соответствующие символы совпадают и строки эквивалентны после всех backspace операций, верните true; в противном случае верните false. 😎 Решение:
class Solution {
public:
bool backspaceCompare(string S, string T) {
int i = S.length() - 1, j = T.length() - 1;
int skipS = 0, skipT = 0;
while (i >= 0 || j >= 0) {
while (i >= 0) {
if (S[i] == '#') { skipS++; i--; }
else if (skipS > 0) { skipS--; i--; }
else break;
}
while (j >= 0) {
if (T[j] == '#') { skipT++; j--; }
else if (skipT > 0) { skipT--; j--; }
else break;
}
if (i >= 0 && j >= 0 && S[i] != T[j]) {
return false;
}
if ((i >= 0) != (j >= 0)) {
return false;
}
i--; j--;
}
return true;
}
};
Ставь 👍 и забирай 📚 Базу знаний3 207
Спутниковый интернет для бизнеса на выгодных условиях
Индивидуальные условия на подключение безлимитного спутникового интернета и поставку VSAT оборудованияв любую точку России.
AltegroSky - мощная спутниковая сеть для Ваших задач: 9 спутников (Ka- и Ku-диапазоны), 8 профессиональных VSAT платформ, гарантированные скорости, высокая доступность канала связи (99,9%), подключение и интеграция корпоративных сервисов на удаленном объекте.
Спутниковый тест-драйв, оперативное подключение, оборудование в наличии.
Получить предложение
#реклама
altegrosky.ru
О рекламодателе
3 207
Задача: 894. All Possible Full Binary Trees
Сложность: medium
Учитывая целое число n, верните список всех возможных полных бинарных деревьев с узлами. Каждый узел каждого дерева в ответе должен иметь Node.val == 0. Каждый элемент ответа является корневым узлом одного возможного дерева. Вы можете вернуть конечный список деревьев в любом порядке. Полное бинарное дерево - это бинарное дерево, в котором каждый узел имеет ровно 0 или 2 дочерних.
Пример:
Input: n = 7 Output: [[0,0,0,null,null,0,0,null,null,0,0],[0,0,0,null,null,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,null,null,null,null,0,0],[0,0,0,0,0,null,null,0,0]]👨💻 Алгоритм: 1⃣Если n четное, вернуть пустой список, так как полное бинарное дерево не может иметь четное количество узлов. 2⃣Если n == 1, вернуть дерево с одним узлом. Для всех возможных значений i от 1 до n-1 с шагом 2: Создать левое поддерево с i узлами. Создать правое поддерево с n-1-i узлами. Объединить все комбинации левого и правого поддеревьев с новым корнем, добавив их в список результатов. 3⃣Вернуть список результатов. 😎 Решение:
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(0), left(nullptr), right(nullptr) {}
};
class Solution {
public:
vector<TreeNode*> allPossibleFBT(int n) {
if (n % 2 == 0) return {};
if (n == 1) return {new TreeNode(0)};
vector<TreeNode*> result;
for (int i = 1; i < n; i += 2) {
vector<TreeNode*> leftTrees = allPossibleFBT(i);
vector<TreeNode*> rightTrees = allPossibleFBT(n - 1 - i);
for (auto left : leftTrees) {
for (auto right : rightTrees) {
TreeNode* root = new TreeNode(0);
root.left = left;
root.right = right;
result.push_back(root);
}
}
}
return result;
}
};
Ставь 👍 и забирай 📚 Базу знаний3 207
Задача: 1064. Fixed Point
Сложность: easy
Дан массив различных целых чисел arr, отсортированный в порядке возрастания. Верните наименьший индекс i, который удовлетворяет условию arr[i] == i. Если такого индекса нет, верните -1.
Пример:
Input: arr = [-10,-5,0,3,7]
Output: 3
Explanation: For the given array, arr[0] = -10, arr[1] = -5, arr[2] = 0, arr[3] = 3, thus the output is 3.
👨💻 Алгоритм:
1⃣Инициализируйте значение left как 0, right как N - 1 и answer как -1.
2⃣Пока размер области поиска не равен нулю, то есть left <= right, выполните следующие шаги: найдите mid как mid = (left + right) / 2. Сравните arr[mid] и mid: если arr[mid] = mid, сохраните mid в answer и перейдите в левую часть, изменив right на mid - 1; если arr[mid] < mid, перейдите в правую часть, изменив left на mid + 1; если arr[mid] > mid, перейдите в левую часть, изменив right на mid - 1.
3⃣Верните answer.
😎 Решение:
class Solution {
public:
int fixedPoint(vector<int>& arr) {
int left = 0, right = arr.size() - 1;
int answer = -1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] == mid) {
answer = mid;
right = mid - 1;
} else if (arr[mid] < mid) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return answer;
}
};
Ставь 👍 и забирай 📚 Базу знаний3 207
Задача: 1278. Palindrome Partitioning III
Сложность: hard
Вам дана строка s, содержащая строчные буквы, и целое число k. Вам нужно: Сначала заменить некоторые символы s на другие строчные английские буквы. Затем разделить s на k непустых непересекающихся подстрок так, чтобы каждая подстрока была палиндромом. Верните минимальное количество символов, которое нужно изменить, чтобы разделить строку.
Пример:
Input: s = "abc", k = 2 Output: 1👨💻 Алгоритм: 1⃣Используйте динамическое программирование для вычисления количества изменений, необходимых для превращения любой подстроки в палиндром. 2⃣Используйте еще одно динамическое программирование для разбиения строки на k палиндромических подстрок с минимальным количеством изменений. 3⃣Верните минимальное количество изменений, найденное во втором шаге. 😎 Решение:
class Solution {
public:
int minChangesToMakePalindrome(string s, int k) {
int n = s.length();
vector<vector<int>> dp1(n, vector<int>(n, 0));
for (int length = 1; length <= n; length++) {
for (int i = 0; i <= n - length; i++) {
int j = i + length - 1;
dp1[i][j] = minChangeToPalindrome(s, i, j);
}
}
vector<vector<int>> dp2(n + 1, vector<int>(k + 1, INT_MAX));
dp2[0][0] = 0;
for (int i = 1; i <= n; i++) {
for (int kk = 1; kk <= k; kk++) {
for (int j = 0; j < i; j++) {
dp2[i][kk] = min(dp2[i][kk], dp2[j][kk - 1] + dp1[j][i - 1]);
}
}
}
return dp2[n][k];
}
private:
int minChangeToPalindrome(const string& s, int i, int j) {
int changes = 0;
while (i < j) {
if (s[i] != s[j]) {
changes++;
}
i++;
j--;
}
return changes;
}
};
Ставь 👍 и забирай 📚 Базу знаний3 207
Задача: 1011. Capacity To Ship Packages Within D Days
Сложность: medium
На конвейерной ленте находятся пакеты, которые должны быть отправлены из одного порта в другой в течение нескольких дней. i-й пакет на конвейерной ленте имеет массу weights[i]. Каждый день мы загружаем корабль пакетами на конвейерной ленте (в порядке, заданном весами). Мы не можем загрузить больше груза, чем максимальная грузоподъемность корабля. Верните наименьшую грузоподъемность корабля, при которой все посылки на конвейере будут отправлены в течение нескольких дней.
Пример:
Input: weights = [1,2,3,4,5,6,7,8,9,10], days = 5 Output: 15👨💻 Алгоритм: 1⃣Определение диапазона возможных ответов: Минимальная грузоподъемность должна быть не меньше максимального веса одного пакета (чтобы хотя бы один пакет можно было загрузить). Максимальная грузоподъемность - это сумма всех весов (если все пакеты будут отправлены за один день). 2⃣Использование бинарного поиска: Примените бинарный поиск в диапазоне от минимальной до максимальной грузоподъемности, чтобы найти наименьшую грузоподъемность, при которой все пакеты можно отправить за заданное количество дней. 3⃣Проверка возможности отправки всех пакетов за заданное количество дней: Напишите вспомогательную функцию, которая проверяет, можно ли отправить все пакеты при заданной грузоподъемности за определенное количество дней. Эта функция проходит по списку весов и считает количество необходимых дней для отправки всех пакетов при текущей грузоподъемности. 😎 Решение:
class Solution {
public:
int shipWithinDays(vector<int>& weights, int D) {
auto canShipInDays = [&](int capacity) {
int days = 1, total = 0;
for (int weight : weights) {
if (total + weight > capacity) {
days++;
total = 0;
}
total += weight;
}
return days <= D;
};
int left = *max_element(weights.begin(), weights.end());
int right = accumulate(weights.begin(), weights.end(), 0);
while (left < right) {
int mid = (left + right) / 2;
if (canShipInDays(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
};
Ставь 👍 и забирай 📚 Базу знаний3 207
Задача: 713. Subarray Product Less Than K
Сложность: medium
Если задан массив целых чисел nums и целое число k, верните количество смежных подмассивов, в которых произведение всех элементов в подмассиве строго меньше k.
Пример:
Input: nums = [10,5,2,6], k = 100 Output: 8👨💻 Алгоритм: 1⃣Инициализируйте переменные для отслеживания текущего произведения и количества допустимых подмассивов. Используйте два указателя для границ подмассива. 2⃣Перемещайте правый указатель по массиву и умножайте текущий элемент на текущее произведение. Если произведение становится больше или равно k, перемещайте левый указатель, уменьшая произведение до тех пор, пока оно снова не станет меньше k. 3⃣Подсчитайте количество подмассивов с текущим правым указателем, добавив к общему количеству допустимых подмассивов разницу между правым и левым указателями. 😎 Решение:
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
if (k <= 1) return 0;
int product = 1, count = 0, left = 0;
for (int right = 0; right < nums.size(); right++) {
product *= nums[right];
while (product >= k) {
product /= nums[left];
left++;
}
count += right - left + 1;
}
return count;
}
Ставь 👍 и забирай 📚 Базу знаний3 207
Задача: 1360. Number of Days Between Two Dates
Сложность: easy
Напишите программу для подсчета количества дней между двумя датами.
Даты даны в виде строк в формате YYYY-MM-DD, как показано в примерах.
Пример:
Input: date1 = "2019-06-29", date2 = "2019-06-30" Output: 1👨💻 Алгоритм: 1⃣Преобразование строк в даты Используйте встроенные функции для преобразования строковых представлений дат в объекты дат. 2⃣Вычисление разницы в днях Вычислите разницу между двумя объектами дат в днях. 3⃣Возвращение результата Верните абсолютное значение разницы в днях для получения положительного числа. 😎 Решение:
#include <iostream>
#include <string>
#include <cmath>
#include <ctime>
class Solution {
public:
int daysBetweenDates(std::string date1, std::string date2) {
std::tm tm1 = {}, tm2 = {};
strptime(date1.c_str(), "%Y-%m-%d", &tm1);
strptime(date2.c_str(), "%Y-%m-%d", &tm2);
std::time_t time1 = std::mktime(&tm1);
std::time_t time2 = std::mktime(&tm2);
return std::abs((time2 - time1) / (60 * 60 * 24));
}
};
Ставь 👍 и забирай 📚 Базу знаний3 207
Гайд для HRD и HRBP по проведению эффективных вебинаров
Как HRD и HRBP ускорить адаптацию и обучение новых сотрудников с помощью вебинаров?
Гайд от МТС Линк по подготовке и проведению эффективных вебинаров.
✅ В гайде:
- Как лучше использовать вебинары для онбординга и обучения новых сотрудников;
- Как упростить рекрутинг и снизить нагрузку на HR-команду;
- Как ускорить адаптацию новичков и сократить отток на испытательном сроке;
- Как сэкономить время на организации вебинара и пригласить всех участников в 2 клика.
Бонус внутри: 5 прикладных советов по контролю внимания участников во время вебинара
✨ Скачайте гайд бесплатно по ссылке
Скачать
#реклама 16+
mts-link.ru
О рекламодателе
3 207
Задача: 399. Evaluate Division
Сложность: medium
Вам дан массив пар переменных equations и массив вещественных чисел values, где equations[i] = [Ai, Bi] и values[i] представляют уравнение Ai / Bi = values[i]. Каждая Ai или Bi - это строка, представляющая одну переменную. Вам также даны некоторые запросы, где queries[j] = [Cj, Dj] представляет j-й запрос, в котором вы должны найти ответ для Cj / Dj = ?. Верните ответы на все запросы. Если ни один ответ не может быть определен, верните -1.0. Замечание: входные данные всегда действительны. Можно предположить, что вычисление запросов не приведет к делению на ноль и что противоречия нет. Примечание: Переменные, которые не встречаются в списке уравнений, являются неопределенными, поэтому для них ответ не может быть определен.
Пример:
Input: equations = [["a","b"],["b","c"]], values = [2.0,3.0], queries = [["a","c"],["b","a"],["a","e"],["a","a"],["x","x"]] Output: [6.00000,0.50000,-1.00000,1.00000,-1.00000]👨💻 Алгоритм: 1⃣Создание графа: Представьте каждую переменную как узел в графе. Используйте уравнения для создания ребер между узлами, где каждое ребро имеет вес, равный значению уравнения (Ai / Bi = values[i]). Создайте также обратные ребра с обратным весом (Bi / Ai = 1 / values[i]). 2⃣Поиск пути: Для каждого запроса используйте поиск в глубину (DFS) или поиск в ширину (BFS) для поиска пути от Cj до Dj. Если путь найден, вычислите произведение весов вдоль пути, чтобы найти значение Cj / Dj. Если путь не найден, верните -1.0. 3⃣Обработка запросов: Пройдитесь по всем запросам и используйте граф для вычисления результатов каждого запроса. 😎 Решение:
using namespace std;
class Solution {
public:
vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
unordered_map<string, unordered_map<string, double>> graph;
for (int i = 0; i < equations.size(); ++i) {
string A = equations[i][0], B = equations[i][1];
double value = values[i];
graph[A][B] = value;
graph[B][A] = 1.0 / value;
}
vector<double> results;
for (auto& query : queries) {
string C = query[0], D = query[1];
if (!graph.count(C) || !graph.count(D)) {
results.push_back(-1.0);
} else {
results.push_back(bfs(C, D, graph));
}
}
return results;
}
private:
double bfs(const string& start, const string& end, unordered_map<string, unordered_map<string, double>>& graph) {
queue<pair<string, double>> q;
q.push({start, 1.0});
unordered_set<string> visited;
while (!q.empty()) {
auto [current, product] = q.front(); q.pop();
if (current == end) return product;
visited.insert(current);
for (auto& [neighbor, value] : graph[current]) {
if (!visited.count(neighbor)) {
q.push({neighbor, product * value});
}
}
}
return -1.0;
}
};
Ставь 👍 и забирай 📚 Базу знаний3 207
Гайд по эффективным онлайн-встречам для отделов закупок
Как специалистам по закупкам и тендерам экономить время на онлайн-совещаниях, сократить время на подготовку ТЗ и ускорить цикл закупок?
Гайд МТС Линк — чек-листы, кейсы и подходы для упрощения коммуникации закупщиков с внутренними заказчиками и подрядчиками с помощью онлайн-встреч.
✅ В гайде:
- Как создать постоянную ссылку на синки с коллегами или поставщиками и подключаться в 2 клика;
- Как ускорить сбор требований без долгих переписок и конфликтов с юр.отделом;
- Как обсуждать ТЗ и сразу фиксировать договоренности с помощью ИИ;
- Как вести переговоры с подрядчиками и оперативно согласовать ключевые этапы сделки;
- Как отслеживать выполнение условий контракта.
Бонус внутри: 5 способов не выгореть от бесконечных синков.
✨ Скачайте гайд бесплатно по ссылке
Скачать
#реклама 16+
mts-link.ru
О рекламодателе
3 207
Задача: 115. Distinct Subsequences
Сложность: hard
Даны две строки s и t. Верните количество различных подпоследовательностей строки s, которые равны строке t.
Пример:
Input: s = "rabbbit", t = "rabbit" Output: 3 Explanation: Из строки s = "rabbbit" можно получить "rabbit" тремя разными способами, выбирая разные b на позиции 2, 3 и 4.👨💻 Алгоритм: 1⃣Реализуем рекурсивную функцию recurse(i, j), где i — текущий индекс в строке s, а j — в строке t. Используем хэш-таблицу memo для кэширования результатов recurse(i, j). 2⃣Базовые случаи: Если j == t.length() — вся строка t успешно сопоставлена, возвращаем 1. Если i == s.length() — строка s закончилась до завершения t, возвращаем 0. 3⃣Если s[i] == t[j], то у нас два варианта: использовать символ s[i] → recurse(i+1, j+1) пропустить символ s[i] → recurse(i+1, j) Если s[i] != t[j], продолжаем только с recurse(i+1, j). Результат сохраняем в memo и возвращаем. 😎 Решение:
class Solution {
private:
unordered_map<string, int> memo;
public:
int numDistinct(string s, string t) {
if (s.size() < t.size()) return 0;
if (s == t || t.empty()) return 1;
string key = to_string(s.size()) + "," + to_string(t.size());
if (memo.find(key) != memo.end()) return memo[key];
int N = s.size(), M = t.size();
int ans = numDistinct(s.substr(0, N - 1), t);
if (s[N - 1] == t[M - 1])
ans += numDistinct(s.substr(0, N - 1), t.substr(0, M - 1));
memo[key] = ans;
return ans;
}
};
Ставь 👍 и забирай 📚 Базу знаний3 207
Repost from easyoffer
🎉 easyoffer 2.0 — релиз уже в этом месяце!
Вас ждут новые фичи, о которых мы ранее даже не упоминали. Они сделают путь к офферам ещё быстрее и эффективнее. Расскажу о них чуть позже 👀
В честь запуска мы готовим ограниченную акцию:
Первые 500 покупателей получат:
🚀 PRO тариф на 1 год с 50% скидкой
Что нужно сделать:
🔔 Подпишитесь на этот Telegram-канал, чтобы первыми узнать о старте релиза. Сообщение появится в нем раньше, чем где-либо еще — вы успеете попасть в число первых 500 и получить максимальную выгоду. 🎁 А еще только для подписчиков канала ценный бонус в подарок к PRO тарифу.
📅 Официальный запуск — уже совсем скоро.
Следите за новостями и не пропустите старт!
3 207
Задача: 302. Smallest Rectangle Enclosing Black Pixels
Сложность: hard
Вам дана бинарная матрица размером m x n, где 0 представляет собой белый пиксель, а 1 представляет собой черный пиксель.
Черные пиксели соединены (то есть существует только одна черная область). Пиксели соединены по горизонтали и вертикали.
Даны два целых числа x и y, которые представляют местоположение одного из черных пикселей. Верните площадь наименьшего (выравненного по осям) прямоугольника, который охватывает все черные пиксели.
Вы должны написать алгоритм со сложностью менее O(mn).
Пример:
Input: image = [["0","0","1","0"],["0","1","1","0"],["0","1","0","0"]], x = 0, y = 2
Output: 6
👨💻 Алгоритм:
1⃣Инициализация границ прямоугольника: Инициализируйте переменные left, right, top и bottom. left и top задаются значениями координат (x, y), right и bottom - значениями x + 1 и y + 1 соответственно.
2⃣Обход всех пикселей: Пройдите по всем координатам (x, y) матрицы. Если текущий пиксель является черным (image[x][y] == 1), обновите границы прямоугольника:
left = min(left, x)
right = max(right, x + 1)
top = min(top, y)
bottom = max(bottom, y + 1)
3⃣Вычисление и возврат площади: После завершения обхода матрицы, верните площадь прямоугольника, используя формулу (right - left) * (bottom - top).
😎 Решение:
class Solution {
public:
int minArea(vector<vector<char>>& image, int x, int y) {
int m = image.size(), n = image[0].size();
int left = searchColumns(image, 0, y, 0, m, true);
int right = searchColumns(image, y + 1, n, 0, m, false);
int top = searchRows(image, 0, x, left, right, true);
int bottom = searchRows(image, x + 1, m, left, right, false);
return (right - left) * (bottom - top);
}
private:
int searchColumns(vector<vector<char>>& image, int i, int j, int top, int bottom, bool opt) {
while (i != j) {
int k = (i + j) / 2;
int t = top;
while (t < bottom && image[t][k] == '0') t++;
if ((t < bottom) == opt) {
j = k;
} else {
i = k + 1;
}
}
return i;
}
int searchRows(vector<vector<char>>& image, int i, int j, int left, int right, bool opt) {
while (i != j) {
int k = (i + j) / 2;
int l = left;
while (l < right && image[k][l] == '0') l++;
if ((l < right) == opt) {
j = k;
} else {
i = k + 1;
}
}
return i;
}
};
Ставь 👍 и забирай 📚 Базу знаний3 207
Задача: 772. Basic Calculator III
Сложность: medium
Реализуйте базовый калькулятор для вычисления простого строкового выражения.
Строка выражения содержит только неотрицательные целые числа, операторы '+', '-', '*', '/' и открывающие '(' и закрывающие скобки ')'. Целочисленное деление должно округляться к нулю.
Предполагается, что данное выражение всегда корректно. Все промежуточные результаты будут находиться в диапазоне [-2^31, 2^31 - 1].
Примечание: нельзя использовать встроенные функции для вычисления строк как математических выражений, такие как eval().
Пример:
Input: s = "1+1"
Output: 2
👨💻 Алгоритм:
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(). Верните сумму всех чисел в стеке.
😎 Решение:
class Solution {
public:
string evaluate(char operator, string first, string second) {
int x = stoi(first);
int y = stoi(second);
int res = 0;
if (operator == '+') {
res = x;
} else if (operator == '-') {
res = -x;
} else if (operator == '*') {
res = x * y;
} else {
res = x / y;
}
return to_string(res);
}
int calculate(string s) {
stack<string> stack;
string curr = "";
char previousOperator = '+';
s += "@";
unordered_set<string> operators = {"+", "-", "*", "/"};
for (char c: s) {
if (isdigit(c)) {
curr += c;
} else if (c == '(') {
stack.push(string(1, previousOperator));
previousOperator = '+';
} else {
if (previousOperator == '*' || previousOperator == '/') {
stack.push(evaluate(previousOperator, stack.top(), curr));
stack.pop();
} else {
stack.push(evaluate(previousOperator, curr, "0"));
}
curr = "";
previousOperator = c;
if (c == ')') {
int currentTerm = 0;
while (operators.find(stack.top()) == operators.end()) {
currentTerm += stoi(stack.top());
stack.pop();
}
curr = to_string(currentTerm);
previousOperator = stack.top()[0];
stack.pop();
}
}
}
int ans = 0;
while (!stack.empty()) {
ans += stoi(stack.top());
stack.pop();
}
return ans;
}
};
Ставь 👍 и забирай 📚 Базу знаний3 207
🐍💩👩💻👩💻🧑💻🧑💻🐧👩💻🧑💻👩💻👩💻
В сети начали массово сливать курсы и книги известных онлайн школ по айти
Вот отсортированная база с тонной материала (постепенно пополняется):
(363 видео, 87 книги) — Python
(415 видео, 68 книги) — Frontend
(143 видео, 33 книги) — ИБ/Хакинг
(352 видео, 89 книги) — С/С++/C#
(343 видео, 87 книги) — Java/QA
(176 видео, 32 книги) — Git/Linux
(174 видео, 91 книги) — DevOps
(167 видео, 53 книги) — PHP/1С
(227 видео, 83 книги) — SQL/БД
(114 видео, 77 книги) — Сисадмин
(107 видео, 43 книги) — BA/SA
(181 видео, 32 книги) — Go/Rust
(167 видео, 43 книги) — Kotlin/Swift
(112 видео, 24 книги) — Flutter
(137 видео, 93 книги) — DS/ML
(113 видео, 82 книги) — GameDev
(183 видео, 37 книги) — Дизайн
(136 видео, 33 книги) — PM/HR
Скачивать ничего не нужно — все выложили в Telegram
3 207
Задача: 1323. Maximum 69 Number
Сложность: easy
Дано положительное целое число num, состоящее только из цифр 6 и 9.
Верните максимальное число, которое можно получить, изменив не более одной цифры (6 становится 9, а 9 становится 6).
Пример:
Input: num = 9669
Output: 9969
Explanation:
Changing the first digit results in 6669.
Changing the second digit results in 9969.
Changing the third digit results in 9699.
Changing the fourth digit results in 9666.
The maximum number is 9969.
👨💻 Алгоритм:
1⃣Преобразуйте входное целое число num в итерируемый и изменяемый объект num_obj.
2⃣Пройдитесь по num_obj и, если найдете цифру 6, замените её на 9 и прекратите итерацию.
3⃣Верните целое число, преобразованное из измененного num_obj.
😎 Решение:
class Solution {
public:
int maximum69Number (int num) {
string numStr = to_string(num);
for (char &c : numStr) {
if (c == '6') {
c = '9';
break;
}
}
return stoi(numStr);
}
};
Ставь 👍 и забирай 📚 Базу знаний3 207
В турагентство на удаленку требуются стажеры
Клиентов предоставим. Можно без опыта и совмещая с основной работой или декретом.
С нас обучение с гарантированной стажировкой.
Доход после обучения:
от 50 000₽ до 220 000₽. Оплата в процессе обучения зависит от вашей вовлеченности.
Задачи:
Помогать людям организовывать путешествия:
подбор самых выгодных предложений на отдых со скидкой до 50% в новых сервисах бронирования.
Условия:
✅ Без опыта — обучение с нуля за 2 месяца, первые выплаты в среднем в течение 2 недель;
✅Удаленная работа или совмещение с офисом (по желанию, зависит от вашего города).
Хотите проверить, подойдет ли это вам? Регистрируйтесь на бесплатный вводный урок, на котором узнаете:
— как подбирать туры для себя и близких с выгодой до 40%
— как получать комиссию 7-10% с каждого тура.
Узнать больше
#реклама 16+
via-tourism-school.space
О рекламодателе
