力扣面试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))
注意点:
let copy = [...nums]
这里是要拷贝一份, 不要写成引用一份let copy = nums
- 如果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]))
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?