
- Главная
- Каталог
- Интернет технологии
- C/C++ | LeetCode
C/C++ | LeetCode
Решения и разбор задач с LeetCode по языку программирования C / C++
Статистика канала
Input
["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex"]
[[[1,3]],[],[],[],[],[]]
Output
[null,1,1,1,1,0]
Explanation
Solution solution = new Solution([1, 3]);
solution.pickIndex(); // return 1. It is returning the second element (index = 1) that has a probability of 3/4.
solution.pickIndex(); // return 1
solution.pickIndex(); // return 1
solution.pickIndex(); // return 1
solution.pickIndex(); // return 0. It is returning the first element (index = 0) that has a probability of 1/4.
Since this is a randomization problem, multiple answers are allowed.
All of the following outputs can be considered correct:
[null,1,1,1,1,0]
[null,1,1,1,1,1]
[null,1,1,1,0,0]
[null,1,1,1,0,1]
[null,1,0,1,0,0]
......
and so on.
{}
👨💻 Алгоритм:
1⃣ Инициализация и предобработка весов:
В конструкторе создайте массив накопительных сумм prefixSums, где каждая позиция будет содержать сумму всех предыдущих весов до текущего индекса включительно.
Также в конструкторе сохраните общую сумму весов totalSum.
2⃣ Генерация случайного числа и выбор индекса:
В функции pickIndex() сгенерируйте случайное число в диапазоне от 0 до общей суммы весов totalSum.
Используйте линейный поиск, чтобы найти первый индекс в prefixSums, который больше или равен сгенерированному числу.
3⃣ Возврат результата:
Верните найденный индекс.
😎 Решение:
class Solution {
private:
vector<int> prefixSums;
int totalSum;
public:
Solution(vector<int>& w) {
int prefixSum = 0;
for (int weight : w) {
prefixSum += weight;
prefixSums.push_back(prefixSum);
}
totalSum = prefixSum;
}
int pickIndex() {
double target = totalSum * ((double) rand() / RAND_MAX);
for (int i = 0; i < prefixSums.size(); ++i) {
if (target < prefixSums[i]) {
return i;
}
}
return prefixSums.size() - 1;
}
};{}
Ставь 👍 и забирай 📚 Базу знаний
Input: candidates = [2,3,5], target = 8 Output: [[2,2,2,2],[2,3,3],[3,5]]
{}
👨💻 Алгоритм:
1⃣Используем рекурсивный бэктрекинг: если остаток суммы remain == 0 — комбинация найдена, добавляем в результат.
2⃣Если remain < 0 — выходим из текущей ветки (комбинация невалидна).
3⃣Для каждой позиции i от start до конца candidates, пробуем включить элемент в комбинацию, вызываем рекурсию с уменьшенным remain, и откатываемся (pop_back) после вызова.
😎 Решение:
class Solution {
public:
void backtrack(int remain, vector<int>& comb, int start,
const vector<int>& candidates,
vector<vector<int>>& results) {
if (remain == 0) {
results.push_back(comb);
return;
} else if (remain < 0) {
return;
}
for (int i = start; i < candidates.size(); ++i) {
comb.push_back(candidates[i]);
backtrack(remain - candidates[i], comb, i, candidates, results);
comb.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> results;
vector<int> comb;
backtrack(target, comb, 0, candidates, results);
return results;
}
};{}
Ставь 👍 и забирай 📚 Базу знаний
Input
["Solution", "pick", "pick", "pick", "pick", "pick", "pick", "pick"]
[[7, [2, 3, 5]], [], [], [], [], [], [], []]
Output
[null, 0, 4, 1, 6, 1, 0, 4]{}
👨💻 Алгоритм:
1⃣Создайте маппинг для чисел, входящих в черный список, чтобы сопоставить их с числами из диапазона [n - len(blacklist), n - 1], которые не входят в черный список.
2⃣Создайте массив для хранения возможных чисел для выбора, исключая числа из черного списка.
3⃣При каждом вызове функции pick() используйте встроенную функцию random для выбора случайного индекса из массива возможных чисел и возвращайте соответствующее значение.
😎 Решение:
class Solution {
public:
Solution(int n, std::vector<int>& blacklist) {
bound = n - blacklist.size();
std::unordered_set<int> blackset(blacklist.begin(), blacklist.end());
int whitelist = bound;
for (int b : blacklist) {
if (b < bound) {
while (blackset.count(whitelist)) {
whitelist++;
}
map[b] = whitelist;
whitelist++;
}
}
}
int pick() {
int r = rand() % bound;
return map.count(r) ? map[r] : r;
}
private:
std::unordered_map<int, int> map;
int bound;
};{}
Ставь 👍 и забирай 📚 Базу знаний
Input: s = "aba"
Output: true{}
👨💻 Алгоритм:
1⃣Создайте вспомогательную функцию checkPalindrome, которая принимает строку s и два указателя i и j. Эта функция возвращает логическое значение, указывающее, является ли подстрока s.substring(i, j) палиндромом.
2⃣Инициализируйте два указателя: i = 0 и j = s.length() - 1. Пока i < j, проверьте, совпадают ли символы в индексах i и j. Если нет, это значит, что нам нужно удалить один из этих символов.
3⃣Попробуйте оба варианта, используя checkPalindrome. Верните true, если либо checkPalindrome(s, i, j - 1), либо checkPalindrome(s, i + 1, j) возвращает true. Если мы выходим из цикла while, это значит, что исходная строка является палиндромом. Поскольку нам не нужно было использовать удаление, следует вернуть true
😎 Решение:
class Solution {
bool checkPalindrome(const string& s, int i, int j) {
while (i < j) {
if (s[i] != s[j]) {
return false;
}
i++;
j--;
}
return true;
}
public:
bool validPalindrome(string s) {
int i = 0;
int j = s.size() - 1;
while (i < j) {
if (s[i] != s[j]) {
return checkPalindrome(s, i, j - 1) || checkPalindrome(s, i + 1, j);
}
i++;
j--;
}
return true;
}
};{}
Ставь 👍 и забирай 📚 Базу знаний
Input: n = 1, k = 1
Output: 0
Explanation: row 1: 0{}
👨💻 Алгоритм:
1⃣Создайте метод depthFirstSearch, который принимает n количество строк в текущем дереве, k позицию целевого узла в последней строке и rootVal значение корня текущего дерева в качестве параметров. Если n равно 1, то в нашем дереве будет единственный узел, и этот узел является целевым узлом. Поэтому возвращаем его значение rootVal.
2⃣Найдите количество узлов в последней строке текущего дерева, totalNodes, которое равно 2^(n-1). Если текущий целевой узел k находится в левой половине последней строки текущего поддерева (то есть k <= totalNodes / 2), переходим в левое поддерево. Если значение текущего узла rootVal равно 0, то значение следующего узла будет 0, иначе следующее значение узла будет 1. Возвращаем вызов depthFirstSearch(n - 1, k, nextRootVal).
3⃣В противном случае, если текущий целевой узел k находится в правой половине последней строки текущего поддерева (то есть k > totalNodes / 2), переходим в правое поддерево. Если значение текущего узла rootVal равно 0, то значение следующего узла будет 1, иначе следующее значение узла будет 0. Кроме того, позиция целевого узла изменится на (k - (totalNodes / 2)). Возвращаем вызов depthFirstSearch(n - 1, newPosition, nextRootVal).
😎 Решение:
class Solution {
public:
int depthFirstSearch(int n, int k, int rootVal) {
if (n == 1) return rootVal;
int totalNodes = 1 << (n - 1);
if (k > totalNodes / 2) {
int nextRootVal = rootVal == 0 ? 1 : 0;
return depthFirstSearch(n - 1, k - totalNodes / 2, nextRootVal);
} else {
int nextRootVal = rootVal == 0 ? 0 : 1;
return depthFirstSearch(n - 1, k, nextRootVal);
}
}
int kthGrammar(int n, int k) {
return depthFirstSearch(n, k, 0);
}
};{}
Ставь 👍 и забирай 📚 Базу знаний
Input: "A" → Output: 1
{}
👨💻 Алгоритм:
1⃣Представим строку как число в 26-ричной системе счисления, где A = 1, B = 2, ..., Z = 26.
2⃣Проходим по строке слева направо, на каждом шаге умножая результат на 26 и прибавляя значение текущего символа (s[i] - 'A' + 1).
3⃣Таким образом, "AB" = 1×26 + 2 = 28.
😎 Решение:
class Solution {
public:
int titleToNumber(string s) {
int result = 0;
for (char c : s) {
result = result * 26 + (c - 'A' + 1);
}
return result;
}
};{}
Ставь 👍 и забирай 📚 Базу знаний
Input: left = "4", right = "1000"
Output: 4{}
👨💻 Алгоритм:
1⃣Найти все палиндромы до корня из right.
2⃣Проверить, являются ли квадраты этих палиндромов палиндромами и лежат ли в диапазоне [left, right].
3⃣Подсчитать количество таких суперпалиндромов.
😎 Решение:
class Solution {
public:
bool isPalindrome(long long x) {
string s = to_string(x);
return s == string(s.rbegin(), s.rend());
}
int superpalindromesInRange(string left, string right) {
long long leftNum = stoll(left);
long long rightNum = stoll(right);
int count = 0;
for (int i = 1; i < 100000; i++) {
string s = to_string(i);
long long palin1 = stoll(s + string(s.rbegin(), s.rend()));
long long palin2 = stoll(s + string(s.rbegin() + 1, s.rend()));
if (palin1 * palin1 > rightNum) {
break;
}
if (palin1 * palin1 >= leftNum && isPalindrome(palin1 * palin1)) {
count++;
}
if (palin2 * palin2 >= leftNum && palin2 * palin2 <= rightNum && isPalindrome(palin2 * palin2)) {
count++;
}
}
return count;
}
};{}
Ставь 👍 и забирай 📚 Базу знаний
Input: jewels = "aA", stones = "aAAbbbb"
Output: 3{}
👨💻 Алгоритм:
1⃣Создайте множество из строки jewels для быстрой проверки, является ли камень драгоценностью. Это позволит эффективно проверять принадлежность каждого камня к драгоценностям.
2⃣Инициализируйте счетчик для подсчета количества камней, которые являются драгоценностями. Пройдите по каждому символу в строке stones и проверьте, содержится ли этот символ в множестве jewels.
3⃣Если символ содержится в множестве, увеличьте счетчик. В конце верните значение счетчика, которое будет количеством камней, являющихся драгоценностями.
😎 Решение:
class Solution {
public:
int numJewelsInStones(string J, string S) {
int ans = 0;
for (char s : S)
for (char j : J)
if (j == s) {
ans++;
break;
}
return ans;
}
};{}
Ставь 👍 и забирай 📚 Базу знаний
Input: edges = [[1,2],[1,3],[2,3]]
Output: [2,3]{}
👨💻 Алгоритм:
1⃣Сначала создаем базовый граф, отслеживая ребра, идущие от узлов с несколькими родителями. В итоге у нас будет либо 2, либо 0 кандидатов на удаление ребра.
2⃣Если кандидатов нет, то каждый узел имеет одного родителя, как в случае 1->2->3->4->1->5. От любого узла идем к его родителю, пока не посетим узел повторно — тогда мы окажемся внутри цикла, и любые последующие посещенные узлы будут частью этого цикла. В этом случае удаляем последнее ребро, входящее в цикл.
3⃣Если есть кандидаты, проверяем, является ли граф, созданный из родителей, корневым деревом. Идем от любого узла к его родителю, пока это возможно, затем выполняем обход в глубину (DFS) от этого корня. Если посещаем каждый узел, удаление последнего из двух кандидатов приемлемо. В противном случае удаляем первое из двух ребер-кандидатов.
😎 Решение:
class Solution {
public:
vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) {
int N = edges.size();
unordered_map<int, int> parent;
vector<vector<int>> candidates;
for (auto& edge : edges) {
if (parent.count(edge[1])) {
candidates.push_back({parent[edge[1]], edge[1]});
candidates.push_back(edge);
} else {
parent[edge[1]] = edge[0];
}
}
int root = orbit(1, parent).node;
if (candidates.empty()) {
auto cycle = orbit(root, parent).seen;
vector<int> ans = {0, 0};
for (auto& edge : edges) {
if (cycle.count(edge[0]) && cycle.count(edge[1])) {
ans = edge;
}
}
return ans;
}
unordered_map<int, vector<int>> children;
for (auto& p : parent) {
children[p.second].push_back(p.first);
}
vector<bool> seen(N + 1, false);
seen[0] = true;
stack<int> stk;
stk.push(root);
while (!stk.empty()) {
int node = stk.top();
stk.pop();
if (!seen[node]) {
seen[node] = true;
for (int c : children[node]) {
stk.push(c);
}
}
}
for (bool b : seen) {
if (!b) {
return candidates[0];
}
}
return candidates[1];
}
private:
struct OrbitResult {
int node;
unordered_set<int> seen;
OrbitResult(int n, unordered_set<int> s) : node(n), seen(s) {}
};
OrbitResult orbit(int node, unordered_map<int, int>& parent) {
unordered_set<int> seen;
while (parent.count(node) && !seen.count(node)) {
seen.insert(node);
node = parent[node];
}
return OrbitResult(node, seen);
}
};{}
Ставь 👍 и забирай 📚 Базу знаний
Input: bits = [1,0,0]
Output: true{}
👨💻 Алгоритм:
1⃣Инициализируйте индекс для итерации по массиву.
2⃣Пройдите по массиву, увеличивая индекс на 1, если текущий бит равен 0, и на 2, если текущий бит равен 1.
3⃣Проверьте, достиг ли индекс последнего элемента массива, и верните результат.
😎 Решение:
bool isOneBitCharacter(vector<int>& bits) {
int i = 0;
while (i < bits.size() - 1) {
i += bits[i] + 1;
}
return i == bits.size() - 1;
}{}
Ставь 👍 и забирай 📚 Базу знанийОтзывы канала
всего 2 отзыва
- Добавлен: Сначала новые
- Добавлен: Сначала старые
- Оценка: По убыванию
- Оценка: По возрастанию
Каталог Телеграм-каналов для нативных размещений
C/C++ | LeetCode — это Telegam канал в категории «Интернет технологии», который предлагает эффективные форматы для размещения рекламных постов в Телеграмме. Количество подписчиков канала в 3.3K и качественный контент помогают брендам привлекать внимание аудитории и увеличивать охват. Рейтинг канала составляет 5.2, количество отзывов – 2, со средней оценкой 5.0.
Вы можете запустить рекламную кампанию через сервис Telega.in, выбрав удобный формат размещения. Платформа обеспечивает прозрачные условия сотрудничества и предоставляет детальную аналитику. Стоимость размещения составляет 1818.18 ₽, а за 6 выполненных заявок канал зарекомендовал себя как надежный партнер для рекламы в TG. Размещайте интеграции уже сегодня и привлекайте новых клиентов вместе с Telega.in!
Вы снова сможете добавить каналы в корзину из каталога
Комментарий