• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

mandyGuan12

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

力扣面试150题经典

88. 合并两个有序数组

思路: 比较两个数组中最大的数(数组是非递减的), 选取大的那个, 从nums1的最后边赋值.

/**
 * @param {number[]} nums1
 * @param {number} m
 * @param {number[]} nums2
 * @param {number} n
 * @return {void} Do not return anything, modify nums1 in-place instead.
 */
var merge = function (nums1, m, nums2, n) {
  let i = m - 1
  let j = n - 1
  let k = m + n - 1  // 指向nums1的最后一个位置
  while (j >= 0) {
    if (nums1[i] > nums2[j]) {
      nums1[k] = nums1[i]
    //   i用掉了, i--
      i--
    } else {
      nums1[k] = nums2[j]
    //   j用掉了, j--
      j--
    }
    k-- // 反正最后一个位置都会被用掉的, --
  }
  console.log(nums1);
}

// 测试用例
merge([1,3,9,0,0],3,[2,10],2)

.
.
输出结果:

.
.
.
.

27. 移除元素

思路:使用左右指针,右指针去遍历,最后返回的左指针的位置即为新数组的长度

/**
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function (nums, val) {
  let left=0
  for (let right = 0; right < nums.length; right++) {
    if(nums[right]!==val){
        nums[left] = nums[right]
        left++
    }
  }
  return left
}

.
.
.
.
.

26. 删除有序数组中的重复项

思路:读题可知,所有重复项元素都应相邻,使用快慢指针。

/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function (nums) {
  let slow = 0
  for (let right = 1; right < nums.length; right++) {
    if (nums[right] !== nums[slow]) {
      slow++
      nums[slow] = nums[right]
    }
  }
  return slow + 1
}

.
.
.
.
.

80. 删除有序数组中的重复项2

思路:使用快慢指针,设置theSame表示重复数字出现的次数。别忘了走到不同数字之后theSame重置方便下次使用。

/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function (nums) {
  let len = nums.length
  if (len < 3) {
    return len
  }
  let slow = 0
  let theSame = 0
  for (let fast = 1; fast < len; fast++) {
    if (nums[fast] !== nums[slow]) {
      slow++
      nums[slow] = nums[fast]
      theSame = 0
    } else {
      theSame++
      if (theSame === 1) {
        slow++
        nums[slow] = nums[fast]
      }
    }
  }
  return slow + 1
}
const nums = [0, 0, 1, 1, 1, 1, 2, 3, 3]
console.log(removeDuplicates(nums))

.
.
.
.
.

169. 多数元素

思路1:暴力解法,依次取出元素并遍历对比,找到多数就return,找不到就循环下一个元素。【不推荐,复杂度高】

/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function (nums) {
  let len = nums.length
  let i, j
  let count = 0
  for (i = 0; i < len; i++) {
    for (j = 0; j < len; j++) {
      if (nums[i] === nums[j]) {
        count++
      }
    }
    if (count > len / 2) {
      return nums[i]
    } else {
      count = 0
    }
  }
}

.
.
.

思路2:将数组排序后,返回的中间值即为多数

/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
     nums.sort((a, b) => a - b)
  return nums[Math.round(nums.length / 2)-1]
};

.
.
.
思路3:摩尔投票法,使用candidate和cnt

/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function (nums) {
  let candidate
  let count = 0
  for (let num of nums) {
    if (count === 0 || num === candidate) {
      count++
      candidate = num
    } else {
      count--
    }
  }
  return candidate
}
nums = [1, 1, 2, 2, 1, 1]
console.log(majorityElement(nums))

注意:这里的题目是“多数”而非“众数”,也就是数量要大于n/2,我一开始用的实验数组为[1, 1, 3, 2, 3, 1],输出3。
.
.
.
.

169. 轮转数组

思路1: 拷贝一份数组, 要轮转几个就换几个

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var rotate = function (nums, k) {
  let len = nums.length
  let copy = [...nums]
  // 如果k>len会报错, 输出undefined, 处理一下
  k %= len
  for (let i = 0; i < len; i++) {
    nums[i] = copy[(i + len - k) % len]
  }
  return nums
}

console.log(rotate([1, 2, 3, 4, 5, 6, 7], 3))

注意点:

  1. let copy = [...nums]这里是要拷贝一份, 不要写成引用一份let copy = nums
  2. 如果k>len会报错, 输出undefined, 处理一下k %= len
    .
    .
    思路2: 三段翻转
/**
 * @param {number[]} nums
 * @param {number} k
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var rotate = function (nums, k) {
  let len = nums.length
  if (k > len) {
    k %= len
  }
  reverse(nums, 0, len - k - 1)
  reverse(nums, len - k, len - 1)
  reverse(nums, 0, len - 1)
  return nums
}

const reverse = function (nums, from, to) {
  let temp
  while (from < to) {
    temp = nums[from]
    nums[from] = nums[to]
    nums[to] = temp
    from++
    to--
  }
  return nums
}

console.log(rotate([1, 2, 3, 4, 5, 6, 7], 3))

.
.
.
.
.

121. 买卖股票的最佳时机

思路1: 暴力解法 j>i 作差保留最大值

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function (prices) {
  let len = prices.length
  let i, j
  let mostProfit = 0,
    tempProfit = 0
  for (i = 0; i < len - 1; i++) {
    for (j = i + 1; j < len; j++) {
      tempProfit = prices[j] - prices[i]
      if (tempProfit > mostProfit) {
        mostProfit = tempProfit
      }
    }
  }
  return mostProfit
}

console.log(maxProfit([7,1,5,3,6,4]))

注意点: prices很大的话, 超出时间限制
.
.
思路2: 一次遍历, 遍历一遍数组, 计算每次到当天为止的minPrice和mostProfit
活在当下, 如果这一天你还没买股票, 你肯定会想, 你在哪一天能够以历史低价收购股票, 又能在哪一天高价抛出呢

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function (prices) {
  let len = prices.length
  let minPrice = prices[0],
    mostProfit = 0
  for (let i = 0; i < len; i++) {
    if (prices[i] < minPrice) {
      minPrice = prices[i]
    } else if (prices[i] - minPrice > mostProfit) {
      mostProfit = prices[i] - minPrice
    }
  }
  return mostProfit
}

console.log(maxProfit([7, 1, 5, 3, 6, 4]))

posted on 2024-09-05 22:56  番茄仔Mandy  阅读(76)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3