持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情🚀🚀
347. 前 K 个高频元素 - 力扣(LeetCode)
哈希map
var topKFrequent = function(nums, k) {
// 遍历数组,将所有结果存储到 map 中
let map = new Map()
nums.forEach(n => {
map.set(n, map.has(n) ? map.get(n)+1 : 1)
})
// 把数据存入一个对象数组
let array = []
for (let [key, value] of map) {
array.push({
key,
value
})
}
//对对象数组根据 value 从大到小排序
array.sort((a, b) => {
return b.value - a.value
})
// 截取前k个,返回其key值组成的数组
return array.slice(0,k).map(item => {
return item.key
})
};
剑指 Offer II 038. 每日温度
思路分析
最简单的就是暴力解法了:
直接两层遍历,第一层定位一个温度,第二层定位离这个温度最近的一次升温是哪天,然后求出两个温度对应索引的差值即可。
问题
在这个暴力遍历的过程中,我们其实做了很多“多余”的事情。
拿第三个索引位上这个 75 来说,我们在定位比 75 高的第一个温度的过程中,就路过了 71、69、72 这三个温度,其中,72 正是 71 对应的目标温度,可我们却像没看见它一样、啥也没干。只有等最外层遍历走到 71 时,我们才又重复了一遍刚刚走过的路、确认了 71 和 72 之间的关系——像这种不必要的重复,我们要想办法把它干掉。
栈结构可以帮我们避免重复操作。
所以这个题目,我们可以:尝试去维持一个递减栈。
代码如下:
var dailyTemperatures = function(temperatures) {
let stack = []
let len = temperatures.length;
let res = new Array(len).fill(0);
for(let i = 0;i < len; i++){
while(stack.length && temperatures[i] > temperatures[stack[stack.length-1]]){
const top = stack.pop()
let diff = i - top;
res[top] = diff
}
stack.push(i)
}
return res
};
155. 最小栈 - 力扣(LeetCode)
O(n)复杂度
getMin 要做的事情,是从一个栈里找出其中最小的数字。我们仍然是抛砖引玉,先说一个大部分人都能想到的思路:
初始化一个最小值变量,它的初始值可以设一个非常大的数(比如 Infinity),然后开始遍历整个栈。在遍历的过程中,如果遇到了更小的值,就把最小值变量更新为这个更小的值。这样遍历结束后,我们就能拿到栈中的最小值了。
这个过程中,我们对栈进行了一次遍历,时间复杂度无疑是 O(n)。
按照这个思路,整个栈的设计我们可以这样写:
const MinStack = function() {
this.stack = []
};
/**
* @param {number} x
* @return {void}
*/
// 栈的入栈操作,其实就是数组的 push 方法
MinStack.prototype.push = function(x) {
this.stack.push(x)
};
/**
* @return {void}
*/
// 栈的入栈操作,其实就是数组的 pop 方法
MinStack.prototype.pop = function() {
this.stack.pop()
};
/**
* @return {number}
*/
// 取栈顶元素,咱们教过的哈,这里我本能地给它一个边界条件判断(其实不给也能通过,但是多做不错哈)
MinStack.prototype.top = function() {
if(!this.stack || !this.stack.length) {
return
}
return this.stack[this.stack.length - 1]
};
/**
* @return {number}
*/
// 按照一次遍历的思路取最小值
MinStack.prototype.getMin = function() {
let minValue = Infinity
const { stack } = this
for(let i=0; i<stack.length;i++) {
if(stack[i] < minValue) {
minValue = stack[i]
}
}
return minValue
};
O(1)复杂度
在这道题里,如果继续沿着栈的思路往下走,我们可以考虑再搞个栈(stack2)出来作为辅助,让这个栈去容纳当前的最小值。
const MinStack = function() {
this.stack = [];
// 定义辅助栈
this.stack2 = [];
};
/**
* @param {number} x
* @return {void}
*/
MinStack.prototype.push = function(x) {
this.stack.push(x);
// 若入栈的值小于当前最小值,则推入辅助栈栈顶
if(this.stack2.length == 0 || this.stack2[this.stack2.length-1] >= x){
this.stack2.push(x);
}
};
/**
* @return {void}
*/
MinStack.prototype.pop = function() {
// 若出栈的值和当前最小值相等,那么辅助栈也要对栈顶元素进行出栈,确保最小值的有效性
if(this.stack.pop() == this.stack2[this.stack2.length-1]){
this.stack2.pop();
}
};
/**
* @return {number}
*/
MinStack.prototype.top = function() {
return this.stack[this.stack.length-1];
};
/**
* @return {number}
*/
MinStack.prototype.getMin = function() {
// 辅助栈的栈顶,存的就是目标中的最小值
return this.stack2[this.stack2.length-1];
};