'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

/**
 * 88.合并两个有序数组
 *
 * https://leetcode.cn/problems/merge-sorted-array/description/?envType=study-plan-v2&envId=top-interview-150
 *
 * 双指针解法
 * - 将两个数组看成队列，每次从数组头部取出较小数字放到结果中
 *
 * - 时间复杂度 O(m + n)
 * - 空间复杂度 O(m + n)
 *
 * @example
 * ```ts
 * const nums1 = [1, 3, 9, 0, 0, 0, 0];
 * const nums2 = [2, 4, 5, 9];
 * mergeTwoSortedArrayV1(nums1, nums2, 3, 4);
 * // [1, 2, 3, 4, 5, 9, 9]
 *
 * const a = [1, 2, 3, 0, 0, 0];
 * const b = [2, 5, 6];
 * mergeTwoSortedArrayV1(a, b, 3, 3);
 * // [1, 2, 2, 3, 5, 6]
 * ```
 */
function mergeTwoSortedArrayV1() {
  var nums1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  var nums2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  var m = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
  var n = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
  var p1 = 0;
  var p2 = 0;
  var temp = [];
  while (p1 < m || p2 < n) {
    if (p1 === m || nums1[p1] > nums2[p2]) {
      temp.push(nums2[p2]);
      p2 += 1;
    } else if (p2 === n || nums1[p1] <= nums2[p2]) {
      temp.push(nums1[p1]);
      p1 += 1;
    }
  }
  for (var i = 0; i < m + n; i++) {
    // eslint-disable-next-line no-param-reassign
    nums1[i] = temp[i];
  }
  return nums1;
}
/**
 * 88.合并两个有序数组
 *
 * https://leetcode.cn/problems/merge-sorted-array/description/?envType=study-plan-v2&envId=top-interview-150
 *
 * 逆向双指针解法
 * - 指针初始位置在尾部，每次向前移动
 * - 不用临时数组 temp，因为不用担心前面的被覆盖
 *
 * - 时间复杂度 O(m + n)
 * - 空间复杂度 O(1)
 *
 * @example
 * ```ts
 * const nums1 = [1, 3, 9, 0, 0, 0, 0];
 * const nums2 = [2, 4, 5, 9];
 * mergeTwoSortedArrayV2(nums1, nums2, 3, 4);
 * // [1, 2, 3, 4, 5, 9, 9]
 *
 * const a = [1, 2, 3, 0, 0, 0];
 * const b = [2, 5, 6];
 * mergeTwoSortedArrayV2(a, b, 3, 3);
 * // [1, 2, 2, 3, 5, 6]
 * ```
 */
function mergeTwoSortedArrayV2() {
  var nums1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  var nums2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  var m = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
  var n = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
  var p1 = m - 1;
  var p2 = n - 1;
  var tail = m + n - 1;
  while (p1 >= 0 || p2 >= 0) {
    var cur = 0;
    if (p1 === -1 || nums1[p1] <= nums2[p2]) {
      cur = nums2[p2];
      p2 -= 1;
    } else if (p2 === -1 || nums1[p1] > nums2[p2]) {
      cur = nums1[p1];
      p1 -= 1;
    }
    // eslint-disable-next-line no-param-reassign
    nums1[tail] = cur;
    tail -= 1;
  }
  return nums1;
}
/**
 *
 * 27.移除元素
 *
 * https://leetcode.cn/problems/remove-element/description/?envType=study-plan-v2&envId=top-interview-150
 *
 * 双指针。
 * - 右指针 right 指向当前将要处理的元素，左指针 left 指向下一个将要赋值的位置。
 * - 如果右指针不等于 val，就将右指针指向的值赋值给左指针位置，左指针右移一位。
 *
 *
 * - 时间复杂度：O(n)，其中 n 为序列的长度。我们只需要遍历该序列至多两次。
 * - 空间复杂度：O(1)。我们只需要常数的空间保存若干变量
 *
 * @example
 * ```ts
 * removeElementInArrayV1([3, 2, 2, 3], 3); // 2
 * removeElementInArrayV1([0, 1, 2, 2, 3, 0, 4, 2], 2); // 5
 * ```
 */
function removeElementInArrayV1(nums, val) {
  var left = 0;
  var n = nums.length;
  for (var right = 0; right < n; right++) {
    if (nums[right] !== val) {
      // eslint-disable-next-line no-param-reassign
      nums[left] = nums[right];
      left += 1;
    }
  }
  return left;
}
/**
 *
 * 27.移除元素
 *
 * https://leetcode.cn/problems/remove-element/description/?envType=study-plan-v2&envId=top-interview-150
 *
 * 对撞指针。
 * - 两个指针初始时分别位于数组的首尾，向中间移动遍历该序列。
 * - 如果左指针 left 指向的元素等于 val，此时将右指针 right 指向的元素复制到左指针 left 的位置，然后右指针 right 左移一位。否则左指针 left 右移一位。
 *
 * - 时间复杂度：O(n)，其中 n 为序列的长度。我们只需要遍历该序列至多一次。
 * - 空间复杂度：O(1)。我们只需要常数的空间保存若干变量
 *
 * 第一种是快慢指针，第二种是对撞指针，同样是双指针，前者同向出发，因此用一个 for 循环实现遍历；后者前后出发，因此用 while 循环判断指针对撞时退出循环
 *
 * @example
 * ```ts
 * removeElementInArrayV2([3, 2, 2, 3], 3); // 2
 * removeElementInArrayV2([0, 1, 2, 2, 3, 0, 4, 2], 2); // 5
 * ```
 */
function removeElementInArrayV2(nums, val) {
  var left = 0;
  var right = nums.length - 1;
  while (left <= right) {
    if (nums[left] === val) {
      // eslint-disable-next-line no-param-reassign
      nums[left] = nums[right];
      right -= 1;
    } else {
      left += 1;
    }
  }
  return left;
}

exports.mergeTwoSortedArrayV1 = mergeTwoSortedArrayV1;
exports.mergeTwoSortedArrayV2 = mergeTwoSortedArrayV2;
exports.removeElementInArrayV1 = removeElementInArrayV1;
exports.removeElementInArrayV2 = removeElementInArrayV2;
