Leetcode 150.逆波兰表达式求值
题目:150.逆波兰表达式求值
初始思路
和括号的匹配有些像,不过不是相等了,而是在栈顶遇到符号的时候进行运算。
代码
var evalRPN = function (tokens) {// 用map存下每个运算符const map = new Map([['+', (a, b) => parseInt(a) + parseInt(b)],['-', (a, b) => a - b],['*', (a, b) => a * b],['/', (a, b) => parseInt((a / b)) | 0]])let stack = []for (const i of tokens) {// 如果tokens中这个字符在map中,即是字符,就进行运算if (map.has(i)) {let fn = map.get(i)let a = stack.pop()let b = stack.pop()// 将运算出来的结果再放入let res = fn(b, a)stack.push(res)} else {// 如果是数字就入栈stack.push(i)}}return stack[0]};
感想
- 使用map存下运算符,简洁方便。
- 在弹出数字的时候,要注意第一下弹出的应该是减数或者是除数,第二次弹出的才是被减数和被除数。
- 加法运算要转换,不然会当成字符串拼接
Leetcode 239.滑动窗口最大值
题目:239.滑动窗口最大值 讲解:https://www.bilibili.com/video/BV1XS4y1p7qj/
初始思路
代码
var maxSlidingWindow = function (nums, k) {// 自定义一个单调队列class MonoQueue {constructor() {this.queue = []}// 如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止enqueue (value) {let back = this.queue[this.queue.length - 1]while (back !== undefined && back < value) {this.queue.pop()back = this.queue[this.queue.length - 1]}this.queue.push(value)}// 如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作dequeue (value) {let front = this.front()if (front === value) {this.queue.shift()}}// 返回队列最前端的元素front () {return this.queue[0]}}let q = new MonoQueue()let i = 0, j = 0let res = []while (j < k) {// 先把滑动窗口内的元素加入单调队列中,按照enqueue的逻辑进行过滤q.enqueue(nums[j++])}res.push(q.front())while (j < nums.length) {q.enqueue(nums[j])q.dequeue(nums[i])res.push(q.front())i++j++}return res};
感想
- 单调队列的思路看懂了,但是代码还是不是很明白。
Leetcode 347.前 K 个高频元素
初始思路
代码
var topKFrequent = function (nums, k) {// 法一:哈希表+sortlet map = new Map()for (let num of nums) {//初始化出现次数为1,之后累加map.set(num, map.has(num) ? map.get(num) + 1 : 1)}if (k === map.size) {//k如果等于map.size,直接返回全部keyreturn [...map.keys()]}let arr = Array.from(map).sort((a, b) => {//从大到小排序return b[1] - a[1]})return arr.slice(0, k).map(n => n[0])//截取前k个key};var topKFrequent = function (nums, k) {//法二:哈希表+桶排序let map = new Map();for (let num of nums) {//初始化出现次数为1,之后累加map.set(num, map.has(num) ? map.get(num) + 1 : 1);}if (k === map.size) {//k如果等于map.size,直接返回全部keyreturn [...map.keys()];}const bucketSort = () => {let arr = [];let res = [];map.forEach((value, key) => {//arr[i]存放频率为i的key数组if (!arr[value]) arr[value] = [key];else arr[value].push(key);});for (let i = arr.length - 1; i >= 0 && res.length < k; i--) {if (arr[i]) {//将数组转换为用逗号分割的参数序列res.push(...arr[i]);}}return res;}return bucketSort();};
感想
- 题解:https://leetcode.cn/problems/top-k-frequent-elements/solution/by-confident-coldenbfp-w28l/
方法一: 将哈希表转成数组,用sort方法排序再截取前k个key
方法二: 桶排序,将频率一致的放在同一个桶里,数组下标i放置频率为i的key,最后倒序取出k个key
sort时间复杂度为为O(nlogn),不符合题意,第二种最好的时间复杂度接近O(n) - 代码随想录是自己定义了堆的结构
