Собрать диапазоны из отсортированного массива без дублей
Задача: дан отсортированный массив без повторов, нужно вывести его как список диапазонов. [0,1,2,4,5,7] превращается в ["0->2", "4->5", "7"]. Формально простая, но на собесе сыпятся на граничных случаях — особенно на последнем элементе массива.
Идея не в том, чтобы искать начало и конец диапазона раздельно. Идёт один проход: фиксируется start текущего диапазона, и как только текущий элемент не равен предыдущему+1 — диапазон закрывается и записывается в ответ, start сдвигается на новый элемент.
Ключевая ловушка — конец массива. Разрыв (nums[i] != nums[i-1]+1) можно встретить и не встретить до последнего индекса, поэтому последний диапазон нужно закрывать и записывать принудительно после выхода из цикла, а не только внутри него.
List summaryRanges(int[] nums) { List result = new ArrayList<>(); int n = nums.length; for (int i = 0; i < n; i) { int start = i; while (i + 1 < n && nums[i + 1] == nums[i] + 1) { i; } result.add(start == i ? String.valueOf(nums[start]) : nums[start] + "->" + nums[i]); } return result; }
Следом спросят про переполнение: если в массиве встретится Integer.MAX_VALUE, то nums[i]+1 в условии сравнения переполнится и уйдёт в MIN_VALUE. В примере выше сравнение идёт как nums[i+1] == nums[i]+1 — при nums[i]=Integer.MAX_VALUE сложение переполнится молча, и если nums[i+1] окажется равным Integer.MIN_VALUE, диапазон склеится неверно. Безопасный вариант — сравнивать через вычитание в long или явно проверять границу перед сложением.
Задача проверяет не столько алгоритм, сколько дисциплину в граничных условиях: пустой массив, один элемент, разрыв на последней паре, переполнение на границе int.
Тренажёр: 900+ вопросов и задач, мок с таймером, план повторов
senior·base — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки