前端程序员学好算法系列(六)队列
利用队列我们可以解决很多问题,js数组也可以实现队列,队列的思想为先近先出,js可以用 push和 shift() 很容易的实现一个队列
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:[3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7
返回其层次遍历结果:
[ [3], [9,20], [15,7] ]
解题:
1.root为空师返回 []
2.定义队列为queue,默认在queue中传入root节点
3.我们记录一下当前节点的层级i,每次从队列头部取出一个节点,如果该节点有左右节点值就把左右节点都重新放入队列
4.res[res.length-1] 能帮我们取到当前操作的师哪层节点。
/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number[][]} */ var levelOrder = function(root) { let res = [] if(root==null){ return [] } let queue = [root] while(queue.length){ let len = queue.length let i = 0 res.push([]) while(i++ < len){ let node = queue.shift() res[res.length-1].push(node.val) if(node.left){ queue.push(node.left) } if(node.right){ queue.push(node.right) } } } return res };
279. 完全平方数
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例 1:
输入: n = 12 输出: 3 解释: 12 = 4 + 4 + 4.
示例 2:
输入: n = 13 输出: 2 解释: 13 = 4 + 9.
解题:
1.创建队列queue 默认传入num = n step为0;
2.创建visited 对象记录 num - i*i 的值是否访问过,访问过时无需重复访问;
3.操作队列弹出队首节点,操作弹出的节点 —— 根据业务生成子节点,判断这些节点 —— 符合业务条件,则return,不符合业务条件,且不在已访问集合,则追加到队尾,并加入已访问集合
/** * @param {number} n * @return {number} */ var numSquares = function(n) { // 创建一个队列默认传入数字num和step 为0 if(n<=1){ return n } let queue = [{'num':n,'step':0}] let visited = {} visited[n] =true while(queue.length){ const {num , step} = queue.shift() if(num==0){ return step } for(let i = 1; num - i*i >=0; i++){ if(!visited[num-i*i]){ queue.push({'num':num-i*i,"step":step +1}) visited[num-i*i] = true } } } };
我们单独对上题中的 num - i*i 重复求解进行优化,同时当a==0 是我们无需继续走完循环直接返回当前步数 step + 1
for(let i = 1; ; i++){ let a = num - i*i if(a<0) break; if(a==0) return step +1; if(!visited[num-i*i]){ queue.push({'num':num-i*i,"step":step +1}) visited[num-i*i] = true } }
347. 前 K 个高频元素
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2]
示例 2:
输入: nums = [1], k = 1 输出: [1]
解题:
1.遍历一遍数组统计每个元素的数量
2.定义priority_queue 保存 [元素的频率,元素的值]
3.排序数组(这里应该用最小堆进行排序)
4.建立res 获取到需要的值
/** * @param {number[]} nums * @param {number} k * @return {number[]} */ var topKFrequent = function(nums, k) { let obj = {} for(let i =0;i<nums.length;i++){ if(!obj[nums[i]]){ obj[nums[i]] = 1 } else { obj[nums[i]] = obj[nums[i]] + 1 } } // priority_queue 保存的内容为[元素的频率,元素值] let priority_queue = [] for(let i in obj){ // if(priority_queue.length==k){ priority_queue.push([obj[i],i]) // } } if(priority_queue.length==1){ return [priority_queue[0][1]] } priority_queue.sort((a,b)=>b[0]-a[0]) let res= [] for(let i =0;i<priority_queue.length;i++){ if(res.length<k){ res.push(priority_queue[i][1]) }else { return res } } return res };