剑指offer-js

Posted 影月

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer-js相关的知识,希望对你有一定的参考价值。

递归

斐波那契数列

// 使用动态数组来保存每个值
var fib = function(n) {
  const arr = []
  arr[0] = 0
  arr[1] = 1
  let i = 2
  while(i<=n) {
    arr[i] = (arr[i - 1] + arr[i -2]) % 1000000007
    i++
  }
  return arr[n]
};

青蛙跳台阶问题

var numWays = function(n) {
  // 假设最后跳一级台阶,共有numWays(n-1)种跳法
  // 假设最后跳两级台阶,共有numWays(n-2)种跳法
  // 所有n级台阶共有numWays(n-1) + numWays(n-2)种跳法
  const arr = []
  arr[0] = 1
  arr[1] = 1
  let i = 2
  while(i <= n) {
    arr[i] = (arr[i - 1] + arr[i - 2]) % 1000000007
    i++
  }
  return arr[n]
};

从上到下打印二叉树

/**
 *  利用两个数组,queue和data,queue存放节点,data存放值
 *     queue每次从队首弹出节点,将值压入data,再将左右节点压入
 *      queue,就实现了二叉树层序遍历
 */
var levelOrder = function(root) {
  if(!root) {
    return []
  }
  // queue保存节点,data保存值
  const queue = [root]
  const data = []
  while(queue.length) {
    const queueFirst = queue.shift()
    data.push(queueFirst.val)
    // 节点存在就压入
    queueFirst.left && queue.push(queueFirst.left)
    queueFirst.right && queue.push(queueFirst.right)
  }
  return data
};

从上到下打印二叉树 II

/**
 *  在32-I的基础上稍作修改,
 *  queue只保存着某一层的值,每一次循环都将一层的节点弹出,并且压入一层的子节点
 */
var levelOrder = function(root) {
  if(!root) {
    return []
  }
  // queue保存节点,data保存值
  const queue = [root] 
  const data = []
  let level = 0 // 表示层数
  while(queue.length) {
    data[level] = [] // 每一层都创建一个新数组
    let length = queue.length // 记录这一层的节点个数
    while(length--) {
      const queueFirst = queue.shift()
      data[level].push(queueFirst.val) // 数据放进对应的层
      queueFirst.left && queue.push(queueFirst.left)
      queueFirst.right && queue.push(queueFirst.right)
      
    } 
    level++ // 层数加一
  }
  return data
};

用两个栈实现队列<br/>

题目描述:
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

var CQueue = function() {
  this.inStack = [] // 负责入栈
  this.outStack = [] // 负责出栈
};

/** 
 * @param {number} value
 * @return {void}
 */
CQueue.prototype.appendTail = function(value) {
  this.inStack.push(value)
};

/**
 * @return {number}
 * 每执行一次deleteHead操作,如果outStack空了,就把inStack中所有元素都压入outStack
 */
CQueue.prototype.deleteHead = function() {
  let {inStack, outStack} = this
  if(!outStack.length) {
    while(inStack.length) {
      outStack.push(inStack.pop())
    }
  }
  return outStack.pop() || -1
};

/**
 * Your CQueue object will be instantiated and called as such:
 * var obj = new CQueue()
 * obj.appendTail(value)
 * var param_2 = obj.deleteHead()
 */

包含min函数的栈<br/>

题目描述:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

解题思路:参照官网题解,维护一个非严格降序的辅助栈。

/**
 * initialize your data structure here.
 */
var MinStack = function() {
  this.stack1 = [] // 保存所有元素 
  this.stack2 = [] // 保持降序的栈
};

// 为了后面多次使用,简单封装
Array.prototype.top = function() {
  return this[this.length - 1]
}

/** 
 * @param {number} x
 * @return {void}
 * 当stack2为空或者当前值小于等于stack2栈顶值,则压入
 */
MinStack.prototype.push = function(x) {
  this.stack1.push(x)
  if(x <= this.stack2.top() || this.stack2.length === 0) {
    this.stack2.push(x)
  }
};

/**
 * @return {void}
 */
MinStack.prototype.pop = function() {
  if(this.stack2.top() === this.stack1.top()) {
    this.stack2.pop()
  }
  return this.stack1.pop()
};

/**
 * @return {number}
 */
MinStack.prototype.top = function() {
  return this.stack1.top()
};

/**
 * @return {number}
 */
MinStack.prototype.min = function() {
  return this.stack2.top()
};

队列的最大值

题目描述:请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。

若队列为空,pop_front 和 max_value 需要返回 -1

var MaxQueue = function() {
    this.queue1 = [] // 保存所有元素
    this.queue2 = [] // 保持非严格降序队列
};

/**
 * @return {number}
 */
MaxQueue.prototype.max_value = function() {
    return this.queue2[0] || -1
};

Array.prototype.top = function() {
    return this[this.length - 1]
}
/** 
 * @param {number} value
 * @return {void}
 */
MaxQueue.prototype.push_back = function(value) {
    this.queue1.push(value)
    while(this.queue2.length && this.queue2.top() < value) {
        this.queue2.pop()
    }
    this.queue2.push(value)
};

/**
 * @return {number}
 */
MaxQueue.prototype.pop_front = function() {
    if(this.queue2[0] === this.queue1[0]) {
        this.queue2.shift()
    }
    return this.queue1.shift() || -1
};


/**
 * Your MaxQueue object will be instantiated and called as such:
 * var obj = new MaxQueue()
 * var param_1 = obj.max_value()
 * obj.push_back(value)
 * var param_3 = obj.pop_front()
 */

## 堆
### 最小的k个数
题目描述:输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

var getLeastNumbers = function(arr, k) {
 arr.sort((val1, val2) => val1 - val2)
 return arr.slice(0, k)
};

堆解法,待完善...

以上是关于剑指offer-js的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer-js编写-树

LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段

LeetCode(剑指 Offer)- 14- I. 剪绳子

LeetCode(剑指 Offer)- 14- I. 剪绳子

剑指 Offer(第 2 版)完整题解笔记 & C++代码实现(LeetCode版)

剑指 Offer(第 2 版)完整题解笔记 & C++代码实现(LeetCode版)