数组算法汇总(JS)

65 阅读4分钟

二分查找

leetcode.cn/problems/bi…

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var search = function (nums, target) {
  let left = 0,
    right = nums.length - 1
  while (left <= right) {
    const mid = Math.floor((left + right) / 2)
    if (nums[mid] === target) {
      return mid
    } else if (nums[mid] > target) {
      right = mid - 1
    } else {
      left = mid + 1
    }
  }
  return -1
}

二分查找相关题目

搜索插入位置

leetcode.cn/problems/se…

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var searchInsert = function (nums, target) {
  let left = 0,
    right = nums.length - 1
  while (left <= right) {
    const mid = Math.floor((left + right) / 2)
    if (nums[mid] === target) {
      return mid
    } else if (nums[mid] < target) {
      left = mid + 1
    } else {
      right = mid - 1
    }
  }
  return left
}

在排序数组中查找元素的第一个和最后一个位置

leetcode.cn/problems/fi…

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var searchRange = function (nums, target) {
  const res = [-1, -1]
  let left = 0,
    right = nums.length - 1
  while (left <= right) {
    const mid = Math.floor((left + right) / 2)
    if (nums[mid] === target) {
      res[0] = mid
      right = mid - 1
    } else if (nums[mid] < target) {
      left = mid + 1
    } else {
      right = mid - 1
    }
  }
  ;(left = 0), (right = nums.length - 1)
  while (left <= right) {
    const mid = Math.floor((left + right) / 2)
    if (nums[mid] === target) {
      res[1] = mid
      left = mid + 1
    } else if (nums[mid] < target) {
      left = mid + 1
    } else {
      right = mid - 1
    }
  }
  return res
}

x 的平方根

leetcode.cn/problems/sq…

/*
 * @lc app=leetcode.cn id=69 lang=javascript
 *
 * [69] x 的平方根
 */

// @lc code=start
/**
 * @param {number} x
 * @return {number}
 */
var mySqrt = function (x) {
  let left = 1,
    right = x
  while (left <= right) {
    const mid = Math.floor((left + right) / 2)
    const multi = mid * mid
    if (multi === x) {
      return mid
    } else if (multi < x) {
      left = mid + 1
    } else {
      right = mid - 1
    }
  }
  return right
}
// @lc code=end

有效的完全平方数

leetcode.cn/problems/va…

/*
 * @lc app=leetcode.cn id=367 lang=javascript
 *
 * [367] 有效的完全平方数
 */

/**
 * @param {number} num
 * @return {boolean}
 */
var isPerfectSquare = function (num) {
  let l = 1,
    r = num
  while (l <= r) {
    const m = Math.floor((l + r) / 2)
    const multi = m ** 2
    if (multi === num) {
      return true
    } else if (multi < num) {
      l = m + 1
    } else {
      r = m - 1
    }
  }
  return false
}

移除元素

leetcode.cn/problems/re…

/*
 * @lc app=leetcode.cn id=27 lang=javascript
 *
 * [27] 移除元素
 */

// @lc code=start
/**
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function (nums, val) {
  let slow = 0,
    fast = 0
  while (fast < nums.length) {
    if (nums[fast] !== val) {
      nums[slow++] = nums[fast]
    }
    fast++
  }
  return slow
}
// @lc code=end

删除有序数组中的重复项

leetcode.cn/problems/re…

/*
 * @lc app=leetcode.cn id=26 lang=javascript
 *
 * [26] 删除有序数组中的重复项
 */

// @lc code=start
/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function (nums) {
  let slow = 0,
    fast = 1
  while (fast < nums.length) {
    if (nums[slow] !== nums[fast]) {
      nums[++slow] = nums[fast]
    }
    fast++
  }
  return slow + 1
}
// @lc code=end

移动零

leetcode.cn/problems/mo…

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function (nums) {
  let slow = 0,
    fast = 0
  for (; fast < nums.length; fast++) {
    if (nums[fast] !== 0) {
      nums[slow++] = nums[fast]
    }
  }
  for (; slow < nums.length; slow++) {
    nums[slow] = 0
  }
}

比较含退格的字符串

leetcode.cn/problems/ba…

/**
 * @param {string} s
 * @param {string} t
 * @return {boolean}
 */
var backspaceCompare = function (s, t) {
  const stackS = [],
    stackT = []
  for (let i = 0; i < s.length; i++) {
    if (s[i] === '#') {
      stackS.pop()
    } else {
      stackS.push(s[i])
    }
  }
  for (let i = 0; i < t.length; i++) {
    if (t[i] === '#') {
      stackT.pop()
    } else {
      stackT.push(t[i])
    }
  }
  return stackS.join('') === stackT.join('')
}

有序数组的平方

leetcode.cn/problems/sq…

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortedSquares = function (nums) {
  let left = 0,
    right = nums.length - 1
  const res = []
  while (left <= right) {
    const leftMulti = nums[left] ** 2,
      rightMulti = nums[right] ** 2
    if (leftMulti > rightMulti) {
      res.unshift(leftMulti)
      left++
    } else {
      res.unshift(rightMulti)
      right--
    }
  }
  return res
}

长度最小的子数组

leetcode.cn/problems/mi…

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function (target, nums) {
  let start = 0,
    end = 0,
    sum = 0,
    res = Infinity
  for (; end < nums.length; end++) {
    sum += nums[end]
    while (sum >= target) {
      res = Math.min(res, end - start + 1)
      sum -= nums[start++]
    }
  }
  return res === Infinity ? 0 : res
}

水果成篮

leetcode.cn/problems/fr…

/*
 * @lc app=leetcode.cn id=904 lang=javascript
 *
 * [904] 水果成篮
 */

// @lc code=start
/**
 * @param {number[]} fruits
 * @return {number}
 */
var totalFruit = function (fruits) {
  const map = new Map()
  let res = 0,
    start = 0,
    end = 0
  for (; end < fruits.length; end++) {
    map.set(fruits[end], map.get(fruits[end]) + 1 || 1)
    if (map.size <= 2) {
      res = Math.max(res, end - start + 1)
    } else {
      while (map.size > 2) {
        map.set(fruits[start], map.get(fruits[start]) - 1)
        if (map.get(fruits[start]) === 0) {
          map.delete(fruits[start])
        }
        start++
      }
    }
  }
  return res
}
// @lc code=end

最小覆盖子串

leetcode.cn/problems/mi…

/**
 * @param {string} s
 * @param {string} t
 * @return {string}
 */
var minWindow = function (s, t) {
  const map = new Map()
  for (let i = 0; i < t.length; i++) {
    map.set(t[i], map.get(t[i]) + 1 || 1)
  }
  let start = 0,
    end = 0,
    needCnt = map.size,
    minRange = Infinity,
    res = ''
  for (; end < s.length; end++) {
    if (map.has(s[end])) {
      map.set(s[end], map.get(s[end]) - 1)
      if (map.get(s[end]) === 0) {
        needCnt--
      }
    }
    while (needCnt === 0) {
      if (end - start + 1 < minRange) {
        minRange = end - start + 1
        res = s.slice(start, end + 1)
      }
      if (map.has(s[start])) {
        map.set(s[start], map.get(s[start]) + 1)
        if (map.get(s[start]) > 0) {
          needCnt++
        }
      }
      start++
    }
  }
  return res
}

螺旋矩阵 II

leetcode.cn/problems/sp…

/**
 * @param {number} n
 * @return {number[][]}
 */
var generateMatrix = function (n) {
  const res = []
  for (let i = 0; i < n; i++) {
    res[i] = []
  }
  let left = 0,
    top = 0,
    right = n - 1,
    bottom = n - 1,
    cnt = 1
  while (left <= right && top <= bottom) {
    for (let i = left; i <= right; i++) {
      res[top][i] = cnt++
    }
    for (let i = top + 1; i <= bottom; i++) {
      res[i][right] = cnt++
    }
    if (left < right && top < bottom) {
      for (let i = right - 1; i > left; i--) {
        res[bottom][i] = cnt++
      }
      for (let i = bottom; i > top; i--) {
        res[i][left] = cnt++
      }
    }
    top++
    left++
    right--
    bottom--
  }
  return res
}

螺旋矩阵

leetcode.cn/problems/sp…

/**
 * @param {number[][]} matrix
 * @return {number[]}
 */
var spiralOrder = function (matrix) {
  const res = []
  let left = 0,
    right = matrix[0].length - 1,
    top = 0,
    bottom = matrix.length - 1
  while (left <= right && top <= bottom) {
    for (let i = left; i <= right; i++) {
      res.push(matrix[top][i])
    }
    for (let i = top + 1; i <= bottom; i++) {
      res.push(matrix[i][right])
    }
    if (left < right && top < bottom) {
      for (let i = right - 1; i > left; i--) {
        res.push(matrix[bottom][i])
      }
      for (let i = bottom; i > top; i--) {
        res.push(matrix[i][left])
      }
    }
    left++
    top++
    right--
    bottom--
  }
  return res
}

螺旋遍历二维数组

leetcode.cn/problems/sh…

/**
 * @param {number[][]} array
 * @return {number[]}
 */
var spiralArray = function (array) {
  if (array.length === 0) {
    return []
  }
  let left = 0,
    right = array[0].length - 1,
    top = 0,
    bottom = array.length - 1
  const res = []
  while (left <= right && top <= bottom) {
    for (let i = left; i <= right; i++) {
      res.push(array[top][i])
    }
    for (let i = top + 1; i <= bottom; i++) {
      res.push(array[i][right])
    }
    if (left < right && top < bottom) {
      for (let i = right - 1; i > left; i--) {
        res.push(array[bottom][i])
      }
      for (let i = bottom; i > top; i--) {
        res.push(array[i][left])
      }
    }
    left++
    top++
    right--
    bottom--
  }
  return res
}