Leetcode.com, задача №491 (Medium). "Возрастающие подмножества". Часть 2.
!!НАШ БЛОГ ПЕРЕЕХАЛ!!
Мы создали свой сайт! Все материалы, опубликованные в этом блоге, переехали туда.
Наш новый сайт maddevelop.ru
А данную статью вы можете найти по ссылке
Условие
Дан массив типа int. Необходимо найти в нём все различные возрастающие подмножества длиной не меньше 2.
Пример
Входной массив: { 4, 6, 7, 7 }
Выходные подмножества: { 4, 6 }, { 4, 7 }, { 4, 6, 7 }, {4, 6, 7, 7}, { 6, 7 }, { 6, 7, 7}, {7, 7}, { 4, 7, 7}
Уточнения:
- Длина массива не превышает 15 элементов.
- Значения чисел массива лежат в интервале (-100, 100).
- В массиве могут быть одинаковые числа, два одинаковых числа составляют подмножество.
Мой вариант решения показал хорошую скорость выполнения: быстрее 87% прочих вариантов. Рассмотрим самое быстрое решение.
Самый быстрый вариант решения.
Этот вариант рекурсивный. В его основе лежит функция, не возвращающая значения, FindSubsequencesBT(nums, currList, result, startIndex), где nums - входной массив, currList - рассматриваемый список, result - выходной список списков, startIndex - индекс рассматриваемого элемента массива. Входной массив просматривается не с конца, как в моём решении, а с начала.
public class Solution
{
public IList<IList<int>> FindSubsequences(int[] nums)
{
List<IList<int>> result = new List<IList<int>>();
List<int> currList = new List<int>();
FindSubsequencesBT(nums, currList, result, 0);
return result;
}
public void FindSubsequencesBT (int [] nums, List<int> currList,
List<IList<int>> result, int startIndex)
{
if(currList.Count >= 2)
result.Add(new List<int>(currList));
if(startIndex >= nums.Length)
return;
HashSet<int> visited = new HashSet<int>();
for(int i = startIndex;i< nums.Length;i++)
{
if(visited.Contains(nums[i]))
continue;
visited.Add(nums[i]);
if(currList.Count == 0 || nums[i] >= currList[currList.Count-1])
{
currList.Add(nums[i]);
FindSubsequencesBT (nums, currList, result, i+1);
currList.RemoveAt(currList.Count-1);
}
}
}
}
Алгоритм функции следующий:
- Если длина списка currList не меньше двух, то добавляем его в список списков result.
- Если индекс startIndex элемента входного массива превышает индекс последнего элемента nums, то происходит завершение работы функции.
- Создаётся хеш-таблица visited, в которую записываем значения элементы массива nums.
- Далее создаётся цикл с итерациями от startIndex до последнего элемента входного массива nums.
а) если хеш-таблица содержит элемент, то переходим к следующей итерации;
б) добавляем в хеш-таблицу текущий элемент массива nums;
в) если длина списка ненулевая или элемент массива не меньше последнего элемента списка, то :
— добавляем в список элемент массива;
— запускаем функцию FindSubsequencesBT(nums, currList, result, i + 1);
— удаляем последний элемент текущего списка.
Выигрыш во времени выполнения программы происходит, полагаю, из-за того, что в итоговый список списков записываются только подходящие значения.