Рубрики
Без рубрики

LeetCode | Содержит дубликат III

Содержит Повторяющуюся проблему III Дан целочисленный массив nums и два целых числа k… С тегами алгоритмы, программирование, java, информатика.

Содержит дубликат III

Проблема

Учитывая целочисленный массив nums и два целых числа k и t, верните значение true, если в массиве есть два разных индекса i и j, таких что abs(nums[i] – nums[j]) и abs(i – j).

Пример 1:

Input: nums = [1,2,3,1], k = 3, t = 0
Output: true

Пример 2:

Input: nums = [1,0,1,1], k = 1, t = 2
Output: true

Пример 3:

Input: nums = [1,5,9,1,5,9], k = 2, t = 3
Output: false

Подсказка №1

Временная сложность O(n log k) – Это даст указание на то, что сортировка задействована для k элементов.

Подсказка №2

Используйте уже существующее состояние для оценки следующего состояния – например, набор из k отсортированных чисел необходим только для отслеживания. Когда мы обрабатываем следующее число в массиве, мы можем использовать существующее отсортированное состояние, и нет необходимости снова сортировать следующий перекрывающийся набор из k чисел.

Давайте начнем

Как обычно, наша главная цель – решить проблему и в то же время достичь наилучшей временной сложности при минимальной сложности пространства. Если вы новичок в решении проблем или пытаетесь решить проблемы со структурой данных, я предлагаю вам начать с подхода грубой силы, а затем попытаться оптимизировать свое решение с учетом наилучшей сложности времени/пространства.

Анализ

Учитывая целочисленный массив nums и два целых числа k и t, верните значение true, если в массиве есть два разных индекса i и j, таких что abs(nums[i] – nums[j]) и abs(i – j).

  1. Прежде чем перейти к решению или псевдокоду, прочтите постановку задачи пару раз и убедитесь, что вы ее хорошо поняли.
  2. Основываясь на постановке задачи, мы понимаем, что нам нужно найти два различных индекса i и j, таких что abs(nums[i] – nums[j]) и abs(i – j).
  3. На этот раз проблема является умеренной и не такой простой, как предыдущая проблема. Поэтому я собираюсь воспользоваться предоставленными подсказками. Я поделился двумя подсказками, связанными с этой проблемой.
  4. Основываясь на первой подсказке, понятно, что сначала нам нужно отсортировать элементы, а затем, используя отсортированный список, нам нужно найти, есть ли два разных индекса, т.е. удовлетворяющих предоставленному условию.
  5. С помощью сортировки и итерации по всем элементам массива мы можем достичь решения по сложности O (n log k).
  6. Со второй подсказкой мы поняли, что нам нужно поддерживать отсортированные элементы с их состоянием в структуре данных таким образом, чтобы нам не приходилось снова сортировать следующие перекрывающиеся элементы.
  7. С пунктов № 4 по № 6 мы определенно можем выбрать TreeSet (структура данных в Java), которая будет лучшим кандидатом для решения этой проблемы.
  8. И со всеми этими моментами мы также получили подсказку, что эта проблема подпадает под ” Шаблон скользящего окна” .

Скользящее окно – это подсписок или подмассив, который выполняется поверх базовой структуры данных. Структура данных является итеративной и упорядоченной, такой как массив или строка. На высоком уровне вы можете думать об этом как о подмножестве метода двух указателей.

Набор деревьев на Java

Набор деревьев – это отсортированная коллекция, которая расширяет класс AbstractSet и реализует интерфейс NavigableSet.

  • В нем хранятся уникальные элементы
  • Это не сохраняет порядок вставки элементов
  • Он сортирует элементы в порядке возрастания
  • Это не потокобезопасно

В нашем решении мы будем в основном использовать следующие два важных метода древовидного набора.

  • потолок() => Этот метод возвращает наименьший элемент в этом наборе, больший или равный данному элементу, или null, если такого элемента нет.
  • этаж() => Этот метод возвращает наибольший элемент в этом наборе, меньший или равный данному элементу, или null, если такого элемента нет.

Итак, со всеми этими подсказками и анализом давайте начнем писать наш алгоритм или псевдокод.

Алгоритм | Псевдокод

  • Создайте набор деревьев для хранения посещенных или отслеживаемых элементов в массиве.
  • Повторите каждый элемент в массиве и получите следующие два значения
    • низкий => самый высокий элемент в наборе, меньший, чем текущий элемент nums[i]
    • высокий => наименьший элемент в наборе, больший, чем текущий элемент nums[i]
  • if ((low && (long) nums[i] – low)
  • (high && (long) high – nums[i])) возвращает true Это означает, что мы нашли два индекса, которые отвечают требуемым условиям.
    • если условия не выполняются, вставьте текущий элемент nums[i] в набор деревьев отслеживания.

Давайте начнем писать решение.

Перебирайте элементы в массиве. Если мы найдем два индекса, которые соответствуют требуемому условию, сравнивая низкие и высокие значения в наборе деревьев. Это оно. Это наш ответ. * * Данный Массив содержит Дубликат ! * *

Решение (на Java)

    class Solution {
        public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        TreeSet visitedSet = new TreeSet<>();
        for (int i = 0; i < nums.length; i++) {
            Integer low = visitedSet.floor(nums[i]);
            Integer high = visitedSet.ceiling(nums[i]);
            if ((low != null && (long) nums[i] - low <= t) || (high != null && (long) high - nums[i] <= t)) {
                return true;
            }
            visitedSet.add(nums[i]);
            if (i >= k) {
                visitedSet.remove(nums[i - k]);
            }
        }
        return false;
    }
    }

Сложность

Временная сложность => O(n log k) Пространственная сложность => O(k)

Вывод

Эта проблема является очень хорошим примером шаблона скользящего окна. Пожалуйста, ознакомьтесь с другими примерами в этой категории для дальнейшего изучения. Поскольку сложность нашего решения равна O (n log k), это не самое лучшее оптимизированное решение. Основываясь на моих исследованиях и анализе, я обнаружил, что мы могли бы достичь O (n) сложности для этой задачи, используя сортировку по корзинам. Но это немного сложное решение, основанное на моем понимании. Поэтому я оставляю читателям этой статьи возможность опробовать решение O (n) bucket sort в качестве упражнения. Поделитесь своим опытом решения этой проблемы в O (n) сложности в разделе комментариев этой статьи, если вам интересно. Давайте учиться друг у друга.

Рекомендации

Проблема с LeetCode в этой статье:

Проблема с LeetCode в этой статье:

Спасибо, что прочитали этот пост!

Я надеюсь, что эта статья будет в какой-то мере информативной и полезной. Если это так, пожалуйста, поставьте лайк и поделитесь! Следуйте за мной дальше Twitter | LinkedIn для получения соответствующего контента.

Счастливого обучения!

Оригинал: “https://dev.to/geetcloud/leetcode-sep-21-challenge-series-day-2-contains-duplicate-iii-4a01”