
- Главная
- Каталог
- Интернет технологии
- C# | LeetCode
Статистика канала
Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
Output: 5
Explanation: One shortest transformation sequence is "hit" -> "hot" -> "dot" -> "dog" -> cog", which is 5 words long.{}
👨💻 Алгоритм:
1⃣Препроцессинг списка слов: Осуществите препроцессинг заданного списка слов (wordList), чтобы найти все возможные промежуточные состояния слов. Сохраните эти состояния в словаре, где ключом будет промежуточное слово, а значением — список слов, имеющих то же промежуточное состояние.
2⃣Использование очереди для обхода: Поместите в очередь кортеж, содержащий beginWord и число 1, где 1 обозначает уровень узла. Вам нужно вернуть уровень узла endWord, так как он будет представлять длину кратчайшей последовательности преобразования. Используйте словарь посещений, чтобы избежать циклов.
3⃣Поиск кратчайшего пути через BFS (обход в ширину): Пока в очереди есть элементы, получите первый элемент очереди. Для каждого слова определите все промежуточные преобразования и проверьте, не являются ли эти преобразования также преобразованиями других слов из списка. Для каждого найденного слова, которое имеет общее промежуточное состояние с текущим словом, добавьте в очередь пару (слово, уровень + 1), где уровень — это уровень текущего слова. Если вы достигли искомого слова, его уровень покажет длину кратчайшей последовательности преобразования.
😎 Решение:
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
public int LadderLength(string beginWord, string endWord, IList<string> wordList) {
int L = beginWord.Length;
Dictionary<string, List<string>> allComboDict = new Dictionary<string, List<string>>();
foreach (string word in wordList) {
for (int i = 0; i < L; i++) {
string newWord = word.Substring(0, i) + '*' + word.Substring(i + 1, L - i - 1);
if (!allComboDict.ContainsKey(newWord))
allComboDict[newWord] = new List<string>();
allComboDict[newWord].Add(word);
}
}
Queue<Tuple<string, int>> Q = new Queue<Tuple<string, int>>();
Q.Enqueue(new Tuple<string, int>(beginWord, 1));
Dictionary<string, bool> visited = new Dictionary<string, bool>();
visited[beginWord] = true;
while (Q.Any()) {
var node = Q.Dequeue();
string word = node.Item1;
int level = node.Item2;
for (int i = 0; i < L; i++) {
string newWord = word.Substring(0, i) + '*' + word.Substring(i + 1, L - i - 1);
foreach (string adjacentWord in allComboDict.GetValueOrDefault(newWord, new List<string>())) {
if (adjacentWord.Equals(endWord))
return level + 1;
if (!visited.ContainsKey(adjacentWord)) {
visited[adjacentWord] = true;
Q.Enqueue(new Tuple<string, int>(adjacentWord, level + 1));
}
}
}
}
return 0;
}
}{}
Ставь 👍 и забирай 📚 Базу знаний
Input: formula = "H2O"
Output: "H2O"{}
👨💻 Алгоритм:
1⃣Используйте стек для отслеживания текущего уровня скобок.
2⃣Пройдите по строке формулы, анализируя каждый символ: Если символ - это открывающая скобка '(', создайте новый словарь для хранения атомов внутри скобок. Если символ - это закрывающая скобка ')', извлеките словарь из стека и умножьте количества атомов на последующее число, если оно присутствует. Если символ - это атом (начинается с заглавной буквы), извлеките имя атома и его количество, и добавьте его в текущий словарь.
3⃣После завершения обработки строки, объедините все словари из стека и отсортируйте результат.
😎 Решение:
public class Solution {
public string CountOfAtoms(string formula) {
var stack = new Stack<Dictionary<string, int>>();
stack.Push(new Dictionary<string, int>());
int n = formula.Length;
int i = 0;
while (i < n) {
if (formula[i] == '(') {
stack.Push(new Dictionary<string, int>());
i++;
} else if (formula[i] == ')') {
var top = stack.Pop();
i++;
int start = i;
while (i < n && Char.IsDigit(formula[i])) {
i++;
}
int multiplicity = i > start ? int.Parse(formula.Substring(start, i - start)) : 1;
foreach (var name in top.Keys) {
int count = top[name];
if (stack.Peek().ContainsKey(name)) {
stack.Peek()[name] += count * multiplicity;
} else {
stack.Peek()[name] = count * multiplicity;
}
}
} else {
int start = i;
i++;
while (i < n && Char.IsLower(formula[i])) {
i++;
}
string name = formula.Substring(start, i - start);
start = i;
while (i < n && Char.IsDigit(formula[i])) {
i++;
}
int multiplicity = i > start ? int.Parse(formula.Substring(start, i - start)) : 1;
if (stack.Peek().ContainsKey(name)) {
stack.Peek()[name] += multiplicity;
} else {
stack.Peek()[name] = multiplicity;
}
}
}
var countMap = stack.Pop();
var sb = new StringBuilder();
foreach (var name in countMap.Keys.OrderBy(x => x)) {
sb.Append(name);
int count = countMap[name];
if (count > 1) {
sb.Append(count);
}
}
return sb.ToString();
}
}{}
Ставь 👍 и забирай 📚 Базу знаний
Input: accounts = [[1,2,3],[3,2,1]]
Output: 6
Explanation:
1st customer has wealth = 1 + 2 + 3 = 6
2nd customer has wealth = 3 + 2 + 1 = 6
Both customers are considered the richest with a wealth of 6 each, so return 6.{}
👨💻 Алгоритм:
1⃣Пройдите по всем клиентам в массиве accounts.
2⃣Для каждого клиента вычислите сумму денег на всех его банковских счетах и сравните её с максимальным богатством, найденным до этого момента.
3⃣Если текущее богатство больше максимального, обновите максимальное значение. Верните максимальное богатство.
😎 Решение:
public class Solution {
public int MaximumWealth(int[][] accounts) {
int maxWealthSoFar = 0;
foreach (var account in accounts) {
int currCustomerWealth = account.Sum();
maxWealthSoFar = Math.Max(maxWealthSoFar, currCustomerWealth);
}
return maxWealthSoFar;
}
}{}
Ставь 👍 и забирай 📚 Базу знаний
Input: arr = ["un","iq","ue"]
Output: 4{}
👨💻 Алгоритм:
1⃣Использование рекурсивного подхода:
Для каждой строки в массиве arr проверяем, можем ли мы добавить ее к текущей комбинации уникальных символов.
Если можем, добавляем ее и продолжаем рекурсивный вызов для следующей строки.
Если не можем, пропускаем текущую строку и переходим к следующей.
2⃣Проверка уникальности символов:
Для проверки уникальности символов используем множество (set). Если все символы строки уникальны и не пересекаются с символами текущей комбинации, мы можем добавить строку.
3⃣Поиск максимальной длины:
На каждом шаге обновляем максимальную длину, если текущая комбинация уникальных символов длиннее предыдущей максимальной длины.
😎 Решение:
using System;
using System.Collections.Generic;
public class Solution {
public int MaxLength(IList<string> arr) {
return Backtrack(arr, 0, "");
}
private bool IsUnique(string s) {
HashSet<char> charSet = new HashSet<char>(s);
return charSet.Count == s.Length;
}
private int Backtrack(IList<string> arr, int index, string current) {
if (!IsUnique(current)) return 0;
int maxLength = current.Length;
for (int i = index; i < arr.Count; i++) {
maxLength = Math.Max(maxLength, Backtrack(arr, i + 1, current + arr[i]));
}
return maxLength;
}
}{}
Ставь 👍 и забирай 📚 Базу знаний
Input: n = 2, trust = [[1,2]]
Output: 2{}
👨💻 Алгоритм:
1⃣Создание счетчиков доверия:
Инициализируйте массив для подсчета количества людей, которым доверяет каждый человек, и массив для подсчета количества людей, которые доверяют каждому человеку.
2⃣Подсчет доверия:
Пройдитесь по каждому элементу в массиве trust и обновите счетчики: увеличьте количество доверий для того, кто доверяет, и увеличьте количество доверенных людей для того, кому доверяют.
3⃣Проверка условий судьи:
Пройдитесь по массиву людей и найдите того, кто никому не доверяет (количество доверий равно 0) и кому доверяют все остальные (количество доверенных людей равно n-1). Верните метку этого человека. Если такого человека нет, верните -1.
😎 Решение:
public class Solution {
public int FindJudge(int n, int[][] trust) {
if (trust.Length == 0 && n == 1) {
return 1;
}
int[] trustCount = new int[n + 1];
int[] trustedBy = new int[n + 1];
foreach (var t in trust) {
trustCount[t[0]]++;
trustedBy[t[1]]++;
}
for (int i = 1; i <= n; i++) {
if (trustCount[i] == 0 && trustedBy[i] == n - 1) {
return i;
}
}
return -1;
}
}{}
Ставь 👍 и забирай 📚 Базу знаний
Input: num = [1,2,0,0], k = 34
Output: [1,2,3,4]
Explanation: 1200 + 34 = 1234{}
👨💻 Алгоритм:
1⃣Инициализация переменных:
Преобразуйте число k в массив его цифр и переверните оба массива (массив num и массив цифр k).
Завести переменную carry для хранения переноса и инициализировать ее нулем.
Создать пустой массив result для хранения результата.
2⃣Сложение массивов:
Пройдите по элементам массивов num и цифр k, начиная с их конца, сложите соответствующие цифры вместе с переносом (carry).
Если сумма больше 9, сохраните последнюю цифру в текущей позиции результата, а carry установите в 1.
Если сумма меньше 10, установите carry в 0.
Добавьте результат текущего сложения в массив result
3⃣Обработка оставшихся цифр и переноса:
Если один из массивов закончился раньше, продолжайте сложение оставшихся цифр другого массива с переносом.
Если после окончания всех сложений остается перенос (carry), добавьте его в начало массива result.
Переверните массив result обратно и верните его.
😎 Решение:
using System;
using System.Collections.Generic;
public class Solution {
public IList<int> AddToArrayForm(int[] num, int k) {
List<int> result = new List<int>();
int n = num.Length;
for (int i = n - 1; i >= 0; i--) {
k += num[i];
result.Add(k % 10);
k /= 10;
}
while (k > 0) {
result.Add(k % 10);
k /= 10;
}
result.Reverse();
return result;
}
}{}
Ставь 👍 и забирай 📚 Базу знаний
Input: arr = [1,1,2,2,3,3,4,4,5,5], target = 8
Output: 20{}
👨💻 Алгоритм:
1⃣Определить количество зараженных узлов после распространения вредоносного ПО для исходного списка initial.
2⃣Для каждого узла в initial удалить его и вычислить количество зараженных узлов после распространения вредоносного ПО.
3⃣Найти узел, удаление которого минимизирует количество зараженных узлов. Если есть несколько таких узлов, выбрать узел с наименьшим индексом.
😎 Решение:
using System;
using System.Collections.Generic;
public class Solution {
public int MinMalwareSpread(int[][] graph, int[] initial) {
int n = graph.Length;
HashSet<int> initialSet = new HashSet<int>(initial);
Array.Sort(initial);
int minInfected = int.MaxValue;
int bestNode = initial[0];
foreach (int node in initial) {
HashSet<int> infected = new HashSet<int>(initialSet);
infected.Remove(node);
foreach (int i in initialSet) {
if (i != node) {
Dfs(graph, i, infected);
}
}
if (infected.Count < minInfected) {
minInfected = infected.Count;
bestNode = node;
}
}
return bestNode;
}
private void Dfs(int[][] graph, int node, HashSet<int> infected) {
for (int neighbor = 0; neighbor < graph.Length; neighbor++) {
if (graph[node][neighbor] == 1 && !infected.Contains(neighbor)) {
infected.Add(neighbor);
Dfs(graph, neighbor, infected);
}
}
}
}{}
Ставь 👍 и забирай 📚 Базу знаний
Input: root = [1,null,2,null,3,null,4,null,null]
Output: [2,1,3,null,null,null,4]
Explanation: This is not the only correct answer, [3,1,4,null,2] is also correct.{}
👨💻 Алгоритм:
1⃣Инициализация. Создайте пустой список inorder для хранения значений узлов после обхода в порядке возрастания.
2⃣Выполнение обхода в порядке возрастания. Обойдите бинарное дерево поиска (BST) и заполните список inorder значениями узлов в отсортированном порядке.
3⃣Перестроение сбалансированного BST. Определите рекурсивную функцию createBalancedBST, которая принимает список inorder, начальный индекс и конечный индекс в качестве параметров. Если начальный индекс больше конечного, верните null (или эквивалент). Вычислите средний индекс как середину текущего диапазона. Создайте новый узел дерева со значением в среднем индексе. Рекурсивно создайте левое поддерево, используя левую половину текущего диапазона. Рекурсивно создайте правое поддерево, используя правую половину текущего диапазона. Верните корень вновь построенного сбалансированного BST.
😎 Решение:
public class Solution {
public TreeNode BalanceBST(TreeNode root) {
if (root == null) return null;
TreeNode vineHead = new TreeNode(0);
vineHead.right = root;
TreeNode current = vineHead;
while (current.right != null) {
if (current.right.left != null) {
RightRotate(current, current.right);
} else {
current = current.right;
}
}
int nodeCount = 0;
current = vineHead.right;
while (current != null) {
nodeCount++;
current = current.right;
}
int m = (int)Math.Pow(2, Math.Floor(Math.Log(nodeCount + 1) / Math.Log(2))) - 1;
MakeRotations(vineHead, nodeCount - m);
while (m > 1) {
m /= 2;
MakeRotations(vineHead, m);
}
TreeNode balancedRoot = vineHead.right;
return balancedRoot;
}
private void RightRotate(TreeNode parent, TreeNode node) {
TreeNode tmp = node.left;
node.left = tmp.right;
tmp.right = node;
parent.right = tmp;
}
private void LeftRotate(TreeNode parent, TreeNode node) {
TreeNode tmp = node.right;
node.right = tmp.left;
tmp.left = node;
parent.right = tmp;
}
private void MakeRotations(TreeNode vineHead, int count) {
TreeNode current = vineHead;
for (int i = 0; i < count; i++) {
TreeNode tmp = current.right;
LeftRotate(current, tmp);
current = current.right;
}
}
}{}
Ставь 👍 и забирай 📚 Базу знаний
Input: s = "ababcbacadefegdehijhklij"
Output: [9,7,8]{}
👨💻 Алгоритм:
1⃣Создайте словарь для хранения последней позиции каждой буквы в строке.
2⃣Пройдите по строке, отслеживая максимальную позицию текущей части.
3⃣Когда текущая позиция совпадает с максимальной позицией, завершите часть и начните новую.
😎 Решение:
using System;
using System.Collections.Generic;
public class Solution {
public IList<int> PartitionLabels(string s) {
int[] lastPos = new int[26];
for (int i = 0; i < s.Length; i++) {
lastPos[s[i] - 'a'] = i;
}
List<int> partitions = new List<int>();
int j = 0, anchor = 0;
for (int i = 0; i < s.Length; i++) {
j = Math.Max(j, lastPos[s[i] - 'a']);
if (i == j) {
partitions.Add(i - anchor + 1);
anchor = i + 1;
}
}
return partitions;
}
}{}
Ставь 👍 и забирай 📚 Базу знаний
Input: req_skills = ["algorithms","math","java","reactjs","csharp","aws"],
people = [["algorithms","math","java"],["algorithms","math","reactjs"],
["java","csharp","aws"],["reactjs","csharp"],["csharp","math"],["aws","java"]]
Output: [1,2]{}
👨💻 Алгоритм:
1⃣Инициализация и создание масок навыков:
Определите количество людей n и количество необходимых навыков m.
Создайте хэш-таблицу skillId, чтобы сопоставить каждому навыку уникальный индекс.
Создайте массив skillsMaskOfPerson, который будет содержать битовые маски навыков для каждого человека.
2⃣Динамическое программирование (DP):
Создайте массив dp размера 2^m и заполните его значениями (1 << n) - 1.
Установите dp[0] в 0 (базовый случай).
Для каждого skillsMask от 1 до 2^m - 1:
- для каждого человека i:
- вычислите smallerSkillsMask как skillsMask & ~skillsMaskOfPerson[i].
- если smallerSkillsMask отличается от skillsMask, обновите dp[skillsMask], если новая команда лучше (имеет меньше установленных битов).
3⃣Формирование ответа:
Извлеките ответ из dp и верните массив индексов людей, составляющих минимальную достаточную команду.
😎 Решение:
public class Solution {
public int[] SmallestSufficientTeam(string[] req_skills, IList<IList<string>> people) {
int n = people.Count, m = req_skills.Length;
var skillId = new Dictionary<string, int>();
for (int i = 0; i < m; i++) {
skillId[req_skills[i]] = i;
}
var skillsMaskOfPerson = new int[n];
for (int i = 0; i < n; i++) {
foreach (var skill in people[i]) {
if (skillId.ContainsKey(skill)) {
skillsMaskOfPerson[i] |= 1 << skillId[skill];
}
}
}
var dp = new long[1 << m];
Array.Fill(dp, (1L << n) - 1);
dp[0] = 0;
for (int skillsMask = 1; skillsMask < (1 << m); skillsMask++) {
for (int i = 0; i < n; i++) {
int smallerSkillsMask = skillsMask & ~skillsMaskOfPerson[i];
if (smallerSkillsMask != skillsMask) {
long peopleMask = dp[smallerSkillsMask] | (1L << i);
if (BitCount(peopleMask) < BitCount(dp[skillsMask])) {
dp[skillsMask] = peopleMask;
}
}
}
}
long answerMask = dp[(1 << m) - 1];
var ans = new List<int>();
for (int i = 0; i < n; i++) {
if (((answerMask >> i) & 1) == 1) {
ans.Add(i);
}
}
return ans.ToArray();
}
private int BitCount(long value) {
int count = 0;
while (value != 0) {
value &= (value - 1);
count++;
}
return count;
}
}{}
Ставь 👍 и забирай 📚 Базу знанийОтзывы канала
- Добавлен: Сначала новые
- Добавлен: Сначала старые
- Оценка: По убыванию
- Оценка: По возрастанию
Каталог Телеграм-каналов для нативных размещений
C# | LeetCode — это Telegam канал в категории «Интернет технологии», который предлагает эффективные форматы для размещения рекламных постов в Телеграмме. Количество подписчиков канала в 3.3K и качественный контент помогают брендам привлекать внимание аудитории и увеличивать охват. Рейтинг канала составляет 5.2, количество отзывов – 1, со средней оценкой 5.0.
Вы можете запустить рекламную кампанию через сервис Telega.in, выбрав удобный формат размещения. Платформа обеспечивает прозрачные условия сотрудничества и предоставляет детальную аналитику. Стоимость размещения составляет 2237.76 ₽, а за 1 выполненных заявок канал зарекомендовал себя как надежный партнер для рекламы в TG. Размещайте интеграции уже сегодня и привлекайте новых клиентов вместе с Telega.in!
Вы снова сможете добавить каналы в корзину из каталога
Комментарий