阅读 73

前端算法面试必刷题系列[55]

这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。

105. 比较含退格的字符串 (backspace-string-compare)

标签

  • 简单

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果。 # 代表退格字符。

注意:如果对空文本输入退格字符,文本继续为空。

输入:S = "ab#c", T = "ad#c"
输出:true
解释:S 和 T 都会变成 “ac”。
复制代码
输入:S = "ab##", T = "c#d#"
输出:true
解释:S 和 T 都会变成 “”。
复制代码

基本步骤

非常简单,这个问题就是一个栈能解决的,我想底下代码足够解释思路。

写法实现

var backspaceCompare = function(s, t) {
  const transStr = (str) => {
    let stack = []
    str.split('').map(item => {
        if (item === '#') {
            stack.pop()
        } else {
            stack.push(item)
        }
    })
    return stack.join('')
  }
  return transStr(s) === transStr(t)
};

let S = "ab#c", T = "ad#c"
console.log(backspaceCompare(S, T))
复制代码

106. 用栈实现队列 (implement-queue-using-stacks)

标签

  • 栈,队列
  • 简单

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾 int pop() 从队列的开头移除并返回元素 int peek() 返回队列开头的元素 boolean empty() 如果队列为空,返回 true ;否则,返回 false   说明:

你只能使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。   进阶:

你能否实现每个操作均摊时间复杂度为 O(1) 的队列?换句话说,执行 n 个操作的总时间复杂度为 O(n) ,即使其中一个操作可能花费较长时间。

输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]

解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
复制代码

基本思想

这个问题听着复杂,其实理解题意是重点,就是用双栈来模拟队列的 先进先出。输入栈和输出栈分别管输入和输出,用来控制先进先出,因为栈是先入后出。

写法实现

/**
 * Initialize your data structure here.
 */
var MyQueue = function() {
  // 创建两个栈来模拟
  this.inStack = []
  this.outStack = []
};

/**
 * Push element x to the back of queue. 
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.push = function(x) {
  this.inStack.push(x)
};

/**
 * Removes the element from in front of queue and returns that element.
 * @return {number}
 */
MyQueue.prototype.pop = function() {
  // 当输出栈为空,就要把输入栈的元素推入
  if ( this.outStack.length === 0) {
    this.inStackToOutStack()
  }
  // 输出栈 出栈
  return this.outStack.pop()
};

/**
 * Get the front element.
 * @return {number}
 */
MyQueue.prototype.peek = function() {
  if ( this.outStack.length === 0) {
    this.inStackToOutStack()
  }
  // 获取栈顶元素,注意栈顶在数组中最后一个下标位置
  return this.outStack[this.outStack.length -1]
};

/**
 * Returns whether the queue is empty.
 * @return {boolean}
 */
MyQueue.prototype.empty = function() {
  return !this.inStack.length && !this.outStack.length
};

MyQueue.prototype.inStackToOutStack = function () {
  while (this.inStack.length) {
    this.outStack.push(this.inStack.pop())
  }
}

/**
 * Your MyQueue object will be instantiated and called as such:
 * var obj = new MyQueue()
 * obj.push(x)
 * var param_2 = obj.pop()
 * var param_3 = obj.peek()
 * var param_4 = obj.empty()
 */
复制代码

107. 用队列实现栈 (implement-stack-using-queues)

标签

  • 栈,队列
  • 简单

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通队列的全部四种操作(push、top、pop 和 empty)。

实现 MyStack 类:

void push(int x) 将元素 x 压入栈顶。 int pop() 移除并返回栈顶元素。 int top() 返回栈顶元素。 boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。  

注意:

你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

示例:

输入:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]

解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False
复制代码

基本思想

用队列模拟栈,可能更简单些,push 操作时记录下当前队列长度 len,然后入队,将队列新入队元素的前面的所有元素依次出队,再入队,这样就正好反过来,做到栈的特性,之后正常操作就行。

写法实现

var MyStack = function() {
  this.queue = [];
};

/**
 * Push element x onto stack. 
 * @param {number} x
 * @return {void}
 */
MyStack.prototype.push = function(x) {
  // 记录下当前长度
  let len = this.queue.length;
  this.queue.push(x);
  for (let i = 0; i < len; i++) {
    this.queue.push(this.queue.shift());
  }
};

/**
 * Removes the element on top of the stack and returns that element.
 * @return {number}
 */
MyStack.prototype.pop = function() {
  return this.queue.shift();
};

/**
 * Get the top element.
 * @return {number}
 */
MyStack.prototype.top = function() {
  return this.queue[0];
};

/**
 * Returns whether the stack is empty.
 * @return {boolean}
 */
MyStack.prototype.empty = function() {
  return !this.queue.length;
};


/**
 * Your MyStack object will be instantiated and called as such:
 * var obj = new MyStack()
 * obj.push(x)
 * var param_2 = obj.pop()
 * var param_3 = obj.top()
 * var param_4 = obj.empty()
 */
复制代码

另外向大家着重推荐下这个系列的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列

今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 点击此处交个朋友 Or 搜索我的微信号infinity_9368,可以聊天说地 加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我 presious tower shock the rever monster,我看到就通过,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧

参考

文章分类
前端
文章标签