代码随想录算法训练营第二天 | 977. 有序数组的平方、209. 长度最小的子数组

79 阅读1分钟

977. 有序数组的平方

双指针,我的思路是先找到第一个自然数的索引作为右指针,它左边的数作为左指针,左右指针分别向两边移动;
卡哥的思路是数组开头作为左指针,数组结尾作为右指针,一起向中间移动

function sortedSquares(nums: number[]): number[] {
  let r = -1 // 第一个自然数索引
  for (let i = 0; i < nums.length; i++) {
    if (nums[i] >= 0) {
      r = i
      break
    }
  }
  // 如果nums全部为负数
  if (r === -1) {
    const res = []
    for (let i = nums.length - 1; i >= 0; i--) {
      res.push(Math.pow(nums[i], 2))
    }
    return res
  }
  // 如果nums全部为自然数
  if (r === 0) {
    return nums.map(num => Math.pow(num, 2))
  }
  // nums既包含负数又包含自然数
  let l = r - 1 // 此指针从r开始向左移动
  const res = []
  while (l >= 0 || r < nums.length) {
    // 只剩自然数
    if (l < 0) {
      res.push(Math.pow(nums[r], 2))
      r++
      continue
    }
    // 只剩负数
    if (r >= nums.length) {
      res.push(Math.pow(nums[l], 2))
      l--
      continue
    }
    if (nums[l] + nums[r] <= 0) { // 如果自然数<=负数的绝对值
      res.push(Math.pow(nums[r], 2))
      r++
    } else {
      res.push(Math.pow(nums[l], 2))
      l--
    }
  }
  return res
};
function sortedSquares(nums: number[]): number[] {
  let l = 0
  let r = nums.length - 1
  const res = []
  let i = nums.length - 1
  while (l <= r) {
    if (Math.pow(nums[l], 2) >= Math.pow(nums[r], 2)) {
      res[i] = Math.pow(nums[l], 2)
      l++
    } else {
      res[i] = Math.pow(nums[r], 2)
      r--
    }
    i--
  }
  return res
};

209. 长度最小的子数组

这题完全没有思路,只能想到不停增加长度,每次遍历数组,复杂度是O(n²)。
滑动窗口的思路,首先是要确定循环索引是窗口的结尾,然后sum不停累加,如果某一刻sum>=target,就在当前循环中把窗口开始位置不停后移,移到最小满足sum>=target的位置,记录最小数量,然后开始外层循环,即窗口结尾后移

function minSubArrayLen(target: number, nums: number[]): number {
  let cnt = nums.length + 1
  let sum = 0
  let i = 0
  for (let j = 0; j < nums.length; j++) {
    sum += nums[j]
    while (sum >= target) {
      cnt = Math.min(cnt, j - i + 1)
      sum -= nums[i]
      i++
    }
  }
  return cnt === nums.length + 1 ? 0 : cnt
};