/** * По времени: O(n^3) — сортировка O(n log n) + три вложенных уровня (i, j, two pointers) * По памяти: O(1) — не считаем выходной массив с результатами */var fourSum = function(nums, target) { nums.sort((a, b) => a - b); const result = []; const n = nums.length; for (let i = 0; i < n - 3; i++) { // Пропускаем дубликаты для первого числа if (i > 0 && nums[i] === nums[i - 1]) continue; // Минимально возможная сумма для данного i const min1 = nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3]; if (min1 > target) break; // дальше суммы только больше // Максимально возможная сумма для данного i const max1 = nums[i] + nums[n - 1] + nums[n - 2] + nums[n - 3]; if (max1 < target) continue; // для этого i сумма слишком маленькая, берем следующее i for (let j = i + 1; j < n - 2; j++) { // Пропускаем дубликаты для второго числа if (j > i + 1 && nums[j] === nums[j - 1]) continue; // Минимально возможная сумма для данного (i, j) const min2 = nums[i] + nums[j] + nums[j + 1] + nums[j + 2]; if (min2 > target) break; // дальше по j будет только больше // Максимально возможная сумма для данного (i, j) const max2 = nums[i] + nums[j] + nums[n - 1] + nums[n - 2]; if (max2 < target) continue; // сумма слишком маленькая, увеличиваем j let left = j + 1; let right = n - 1; while (left < right) { const currentSum = nums[i] + nums[j] + nums[left] + nums[right]; if (currentSum === target) { result.push([nums[i], nums[j], nums[left], nums[right]]); // Пропускаем дубликаты слева while (left < right && nums[left] === nums[left + 1]) left++; // Пропускаем дубликаты справа while (left < right && nums[right] === nums[right - 1]) right--; left++; right--; } else if (currentSum < target) { left++; } else { right--; } } } } return result;};