# 数组练习

数组和有序联想到双指针,双指针中有对撞指针,求和问题转为求差问题,用空间换时间

# 空间换时间

1. 两数之和 (opens new window)

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]

const arr = [2, 7, 12, 32]
const res = 9

function test(arr, res) {
  const map = {}
  for (let i = 0; i < arr.length; i++) {
    if (map[res - arr[i]] !== undefined) {
      return [i, map[res - arr[i]]]
    } else {
      map[arr[i]] = i
    }
  }
}

console.log(test(arr, res))

# 双指针

真题描述:给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。 输入: nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3 输出: [1,2,2,3,5,6]

// 输入:
// nums1 = [1,2,3,0,0,0], m = 3
// nums2 = [2,5,6], n = 3
// 输出: [1,2,2,3,5,6]
/**
 * @param {number[]} nums1
 * @param {number} m
 * @param {number[]} nums2
 * @param {number} n
 * @return {void} Do not return anything, modify nums1 in-place instead.
 */
const merge = function(nums1, m, nums2, n) {
  let nums1R = m - 1
  let nums2R = n - 1
  let k = m + n - 1 //  为什么不是nums1.length-1 因为无效长度可能超过 n
  while (nums1R >= 0 && nums2R >= 0) {
    if (nums1[nums1R] >= nums2[nums2R]) {
      nums1[k] = nums1[nums1R]
      nums1R--
      k--
    } else {
      nums1[k] = nums2[nums2R]
      nums2R--
      k--
    }
  }
  while (nums2R >= 0) {
    nums1[k] = nums2[nums2R]
    nums2R--
    k--
  }
  return nums1
}

console.log(merge([3, 0, 0, 0], 1, [2, 5, 6], 3))

# 对撞双指针

真题描述:给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]

const nums = [-1, 0, 1, 2, -1, -4] //[-4,-1,-1,0,1,2]

function add(nums) {
  const res = []

  nums = nums.sort((a, b) => {
    return a - b
  })

  const len = nums.length

  for (let i = 0; i < len - 2; i++) {
    // nums[i] 当前固定的指针的值
    let l = i + 1
    let r = len - 1
    while (l < r) {
      if (nums[i] + nums[l] + nums[r] === 0) {
        res.push([nums[i], nums[l], nums[r]])
        l++
        r--
      } else if (nums[i] + nums[l] + nums[r] > 0) {
        r--
      } else {
        l++
      }
    }
  }
  return res
}

// 现在的问题是有一些是重复计算的 当前指针和上一位指针如果还是原来的数字可以直接跳过可以不用计算

function add2(nums) {
  const res = []

  nums = nums.sort((a, b) => {
    return a - b
  })

  const len = nums.length

  for (let i = 0; i < len - 2; i++) {
    // nums[i] 当前固定的指针的值
    let l = i + 1
    let r = len - 1
    if (i > 0 && nums[i] === nums[i - 1]) {
      continue
    }
    while (l < r) {
      if (nums[i] + nums[l] + nums[r] === 0) {
        res.push([nums[i], nums[l], nums[r]])
        l++
        r--
        while (l < r && nums[r] === nums[r + 1]) {
          r--
        }
        while (l < r && nums[l] === nums[l - 1]) {
          l++
        }
      } else if (nums[i] + nums[l] + nums[r] > 0) {
        r--
        while (l < r && nums[r] === nums[r + 1]) {
          r--
        }
      } else {
        l++
        while (l < r && nums[l] === nums[l - 1]) {
          l++
        }
      }
    }
  }
  return res
}
console.log(add2(nums))
上次更新: 2/6/2022, 8:48:39 PM