剑指Offer | JS(一)

209 阅读3分钟

JZ1.二维数组的查找

  • 题目描述: 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
  • 输入:7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
  • 输出:true
function Find(target, array){
    const n = array.length // 存储二维数组的长度
    const m = array[0].length // 二维数组中每个一维数组的长度
    let row = 0, col = m - 1
    
    if (n == 0 || m == 0) return false
    
    while (row <= n - 1 && col >= 0) {
        if (target < array[row][col]) { col -= 1 }
        else if (target > array[row][col]) { row += 1 }
        else if (target == array[row][col]) { return true }
    }
    return false
}

JZ2.替换空格

  • 题目描述: 把字符串 s 中的每个空格替换成"%20"
  • 输入:s = "We are happy."
  • 输出:"We%20are%20happy."
// 方法1 :正则
var replaceSpaceFn1 = function (s) {
     return s.replace(/\s/g, '%20');
};

// 方法2 :循环
var replaceSpaceFn2 = function (s) {
    let sb = ''
    let c = ''
    let len = s.length
    for (let i = 0; i < len; i++) {
        c = s.charAt(i);
        if (c == ' ') sb += "%20";
        else sb += c
    }
    return sb
};

JZ3.从尾到头打印链表

  • 题目描述: 输入一个链表,按链表从尾到头的顺序返回一个数组
  • 输入:head = [1,3,2]
  • 输出:[2,3,1]
/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function printListFromTailToHead(head){
    var arr = []
    while(head!=null){
        arr.push(head.val)
        head = head.next
    }
    return arr.reverse()
}

JZ4.重建二叉树

  • 题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
  • 输入:[1,2,3,4,5,6,7],[3,2,4,1,6,5,7]
  • 输出:{1,2,5,3,4,6,7}
/*
算法思路:
通过【前序遍历列表】确定【根节点 (root)】
将【中序遍历列表】的节点分割成【左分支节点】和【右分支节点】
递归寻找【左分支节点】中的根节点 和 【右分支节点】中的根节点
*/
/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */
// 递归
function reConstructBinaryTree(pre, vin){
    if(pre.length == 0||vin.length==0)return null
    var index = vin.indexOf(pre[0])
    var left = vin.slice(0,index)
    var right = vin.slice(index+1)
    return {
        val:pre[0],
        left:reConstructBinaryTree(pre.slice(1,index+1),left),
        right:reConstructBinaryTree(pre.slice(index+1),right)
    }
}

JZ5.用两个栈实现队列

  • 题目描述: 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
  • 输入:
    • ["CQueue","appendTail","deleteHead","deleteHead"]
    • [[],[3],[],[]]
  • 输出:[null,null,3,-1]
var CQueue = function () {
    this.stack1 = []
    this.stack2 = []
};

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

/**
 * @return {number}
 */
CQueue.prototype.deleteHead = function () {
    if (!this.stack2.length) {
        while (this.stack1.length) {
            this.stack2.push(this.stack1.pop()) // 弹栈
        }
    }
    return this.stack2.pop() || -1
};

JZ6.旋转数组的最小数字

  • 题目描述: 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
  • 输入:[3,4,5,1,2]
  • 输出:1
function minNumberInRotateArray(rotateArray){
    if(!rotateArray){
        return 0
    }
    // 排序
    rotateArray.sort(function(a,b){
        if(a<b) return -1;
        else return 1;
    });
    return rotateArray[0];
}

JZ7.斐波那契数列

F(0) = 0, F(1) = 1 ,F(N) = F(N - 1) + F(N - 2), 其中 N > 1,N ≤ 39

  • 输入:4
  • 输出:3
function Fibonacci(n){
    if(n == 0)return 0
    if(n == 1)return 1
    let first = 1,second = 0,cur = 0
    for(let i = 1;i<n;i++){
        cur=first+second
        second = first
        first = cur
    }return cur
}

JZ8.跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

  • 输入:7
  • 输出:21
function jumpFloor(number){
    if (number < 2) return 1
    let a = 1, b = 1
    for (let i = 2; i <= number; i++) {
        a = a + b
        b = a - b
        a = a >= 1000000007 ? (a - 1000000007) : a;
    }
    return a
}