剑指刷题笔记

数组

1. 剑指 Offer 03. 数组中重复的数字

在这里插入图片描述

/**
 * @param {number[]} nums
 * @return {number}
 */
var findRepeatNumber = function(nums) {
    //对象属性的方法
    // let mapList = {}
    // for(let i = 0;i<nums.length;i++){
    //     if(!mapList.hasOwnProperty(nums[i])){
    //         mapList[nums[i]] = 1
    //     }else{
    //         return nums[i]
    //     }
    // }

    //map方法
    let mapList =new Map()
    for(let i of nums){
        if(!mapList.has(i)){
              mapList.set(i,1)
        }else{
            return i
        }
    }
    return null
};

2. 剑指 Offer 04. 二维数组中的查找

在这里插入图片描述

/**
 1. @param {number[][]} matrix
 2. @param {number} target
 3. @return {boolean}
 */
var findNumberIn2DArray = function(matrix, target) {
    if(matrix.length == 0) return false
    let row = matrix.length
    let col = matrix[0].length
    let i = 0
    let j = col-1
    while(i<row&&j>=0){
        if(matrix[i][j] == target){
            return true
        }else if(matrix[i][j] > target){
            j--
        }else{
            i++
        }
    }
    return false
};

在这里插入图片描述

3. 剑指 Offer 29. 顺时针打印矩阵

在这里插入图片描述

    <script>
      var spiralOrder = function (matrix) {
        let res = []
        if (matrix.length === 0) return res
        let row = matrix.length,
          col = matrix[0].length,
          len = row * col
        let flag = []
        for (let i = 0; i < row; i++) {
          flag[i] = []
          for (let j = 0; j < col; j++) {
            flag[i][j] = false
          }
        }
        let i = 0,
          j = 0
        flag[i][j] = true
        res.push(matrix[i][j])
        while (res.length < len) {
          while (j + 1 < col && flag[i][j + 1] === false) {
            j++
            flag[i][j] = true
            res.push(matrix[i][j])
          }
          while (i + 1 < row && flag[i + 1][j] === false) {
            i++
            flag[i][j] = true
            res.push(matrix[i][j])
          }
          while (j - 1 >= 0 && flag[i][j - 1] === false) {
            j--
            flag[i][j] = true
            res.push(matrix[i][j])
          }
          while (i - 1 >= 0 && flag[i - 1][j] === false) {
            i--
            flag[i][j] = true
            res.push(matrix[i][j])
          }
        }
        return res
      }

      var matrix = [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9],
      ]
      var res = spiralOrder(matrix)
      console.log(res)
    </script>

4. 剑指 Offer 53 - I. 在排序数组中查找数字 I

在这里插入图片描述

var search = function(nums, target) {
      if (
          nums.length === 0 ||
          nums[0] > target ||
          nums[nums.length - 1] < target
        )
          return 0
        //寻找左下限
        let i = 0
        j = nums.length - 1
        while (i <= j) {
          let mid = Math.floor((i + j) / 2)
          if (nums[mid] < target) i = mid + 1 //<= 和 <的区别
          else j = mid - 1
        }
        let left_index = i

        //寻找右下限
        var m = 0,
          n = nums.length - 1
        while (m <= n) {
          let mid = Math.floor((m + n) / 2)
          if (nums[mid] <= target) m = mid + 1
          else n = mid - 1
        }
        let right_index = n
        return right_index - left_index + 1
};

6. 剑指 Offer 53 - II. 0~n-1中缺失的数字

在这里插入图片描述

      var missingNumber = function (nums) {
        if (
          (nums[0] === 0 && nums.length === 1) ||
          (nums[0] === 0 && nums[nums.length - 1] === nums.length - 1)
        )
          return nums.length
        let i = 0,
          j = nums.length - 1
        while (i < j) {
          let mid = Math.floor((i + j) / 2)
          if (nums[mid] === mid) i = mid + 1
          else j = mid
        }
        return i
      }

7. 剑指 Offer 56 - II. 数组中数字出现的次数 II

在这里插入图片描述

/**
 * @param {number[]} nums
 * @return {number}
 */
      var singleNumber = function (nums) {
        let map = new Map()
        let res = 0
        nums.forEach((ele) => {
          if (!map.has(ele)) {
            map.set(ele, true)
          } else {
            map.set(ele, false)
          }
        })
        map.forEach((val, key, map) => {
          if (val) {
            res = key
          }
        })
        return res
      }

字符串

1. 剑指 Offer 58 - II. 左旋转字符串

在这里插入图片描述

var reverseLeftWords = function(s, n) {
    let str1 = s.substring(0,n)
    let str2 = s.substring(n,s.length)
    return str2.concat('',str1)
};

2. 剑指 Offer 58 - I. 翻转单词顺序

在这里插入图片描述

var reverseWords = function(s) {
        let arr = s.split(' ')
        let res = ''
        for (let i = arr.length - 1; i >= 0; i--) {
          if (arr[i].trim() !== '') {
            res = res.concat('', arr[i].trim() + ' ')
          }
        }
        return res.trim()

//方法二
 return s.trim().split(/\s+/).reverse().join(' ')
};

3. 剑指 Offer 67. 把字符串转换成整数

在这里插入图片描述
在这里插入图片描述

var strToInt = function(str) {
        const regexp = /^[+-]?\d+/
        let res = str.trim().match(regexp)
        if (!res) return 0
        else {
          res = res[0].trim()
          const max = Math.pow(2, 31) - 1
          const min = Math.pow(-2, 31)
          if (res > max) return max
          else if (res < min) return min
          else return res
        }
};

链表

1. 剑指 Offer 22. 链表中倒数第k个节点

在这里插入图片描述

var getKthFromEnd = function(head, k) {
    let first = head ,second = head
    for(let i =0;i<k;i++){
        second = second.next
    }
    while(second !== null){
        first = first.next
        second = second.next
    }
    return first
};

2. 剑指 Offer 06. 从尾到头打印链表

在这里插入图片描述

var reversePrint = function(head) {
    var res = []
    while(head){
        res.push(head.val)
        head = head.next
    }
    return res.reverse()
};
//栈先进后出,用unshift模拟
var reversePrint = function(head) {
    var res = []
    while(head){
        res.unshift(head.val)
        head = head.next
    }
    return res
};

3. 剑指 Offer 24. 反转链表

在这里插入图片描述

var reverseList = function(head) {
    if (head === null) return null
    let first = head,second = head.next
    first.next = null   //注意这里
    while(second){
        let tmp = second.next
        second.next = first
        first = second
        second = tmp
    }
    return first
};

4. 剑指 Offer 52. 两个链表的第一个公共节点

在这里插入图片描述

var getIntersectionNode = function(headA, headB) {
    let pa = headA,pb = headB
    while(pa !== pb){
        pa = pa === null? headB:pa.next
        pb = pb === null? headA:pb.next
    }
     return pa
};

5. 剑指 Offer 18. 删除链表的节点

在这里插入图片描述

var deleteNode = function(head, val) {
    if(head.val === val) return head.next
    let first = head
    while(head.next.val !== val) head = head.next
    head.next = head.next.next
    return first
}

6. 剑指 Offer 35. 复杂链表的复制

在这里插入图片描述

var copyRandomList = function(head) {
    let cur = head
    let map = new Map()
    map.set(cur,new Node(cur.val))
    while(cur.next){
        cur = cur.next
        map.set(cur,new Node(cur.val))
    }
    let p = head
    while(p){
        map.get(p).next = map.get(p.next)
        map.get(p).random = map.get(p.random)
        p  = p.next
    }
    return map.get(head)
};

二叉树

  • 层序遍历(广度遍历) 按层遍历 队列实现比较方便
  • 中序遍历 左节点——根节点——右节点 递归

1. 剑指 Offer 55 - I. 二叉树的深度

在这里插入图片描述

var maxDepth = function(root) {
    if(!root) return 0
    let left = maxDepth(root.left)
    let right = maxDepth(root.right)

    return Math.max(left,right)+1
};

2. 剑指 Offer 55 - II. 平衡二叉树

在这里插入图片描述

var isBalanced = function(root) {
    if(!root) return true
    let left = getDepth(root.left)
    let right = getDepth(root.right)
    return isBalanced(root.left)&&isBalanced(root.right)&& Math.abs(right-left)<=1
};
var getDepth = function(root){
    if(!root) return 0
    return Math.max(getDepth(root.left),getDepth(root.right))+1
}

3. 剑指 Offer 27. 二叉树的镜像

在这里插入图片描述

var mirrorTree = function(root) {
    if(!root) return root
    let tmp = root.right
    root.right = root.left
    root.left = tmp
    mirrorTree(root.left)
    mirrorTree(root.right)
    return root
};

4. 剑指 Offer 28. 对称的二叉树

在这里插入图片描述

var isSymmetric = function(root) {
    let newRoot = mirrorTree(root)
    return newRoot === root
};
var mirrorTree = function(root){
    if(!root) return root
    var tmp = root.right
    root.right = root.left
    root.left = tmp
    mirrorTree(root.left)
    mirrorTree(root.right)
    return root
}

5. 剑指 Offer 32 - I. 从上到下打印二叉树

在这里插入图片描述

var levelOrder = function(root) {
    let queue = [],res=[]
    if(!root) return res
    queue.push(root)
    while(queue.length>0){
        let root = queue.shift()
        res.push(root.val)
        if(root.left) queue.push(root.left)
        if(root.right) queue.push(root.right)
    }
    return res
};

6. 剑指 Offer 32 - II. 从上到下打印二叉树 II

在这里插入图片描述

var levelOrder = function(root) {
    let res = []
    if(!root) return res
    let queue = []
    queue.push(root)
    while(queue.length>0){
        let tmp = []
        let curLength = queue.length
        for(let i = 0;i<curLength;i++){
            let node = queue.shift()
            tmp.push(node.val)
            if(node.left) queue.push(node.left)
            if(node.right) queue.push(node.right)
        }
        res.push(tmp)
    }
    return res
};

7. 剑指 Offer 32 - III. 从上到下打印二叉树 III

在这里插入图片描述

var levelOrder = function(root) {
    let res = []
    if(!root) return res
    let queue = []
    queue.push(root)
    let j =0
    while(queue.length>0){
        let tmp = []
        j++
        let curLen = queue.length
        for(let i = 0;i<curLen;i++){
            let node = queue.shift()
            tmp.push(node.val)
            if(node.left) queue.push(node.left)
            if(node.right) queue.push(node.right)
        }
        if(j%2) res.push(tmp)
        else res.push(tmp.reverse())
    }
    return res
};

8. 剑指 Offer 54. 二叉搜索树的第k大节点

在这里插入图片描述

var kthLargest = function(root, k) {
    let arr =[]
    var helper = function(root){
      if(!root) return null
      helper(root.left)
      arr.push(root.val)
      helper(root.right)
      return arr
    }
    arr = helper(root)
    return arr.reverse()[k-1]
};


var kthLargest = function(root, k) {
    let arr =[]
    var helper = function(root){
      if(!root) return null
      helper(root.right)
      arr.push(root.val)
      helper(root.left)
      return arr
    }
    arr = helper(root)
    return arr[k-1]
};

9. 剑指 Offer 68 - II. 二叉树的最近公共祖先

在这里插入图片描述

var lowestCommonAncestor = function(root, p, q) {
    if(!root||p === root ||q === root ) return root
    let left = lowestCommonAncestor(root.left,p,q)
    let right = lowestCommonAncestor(root.right,p,q)
    if(!left) return right
    else if(!right) return left
    else return root
};

10. 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

  • 二叉搜索树:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

在这里插入图片描述

var lowestCommonAncestor = function(root, p, q) {
    if(p.val<root.val&&q.val<root.val) return lowestCommonAncestor(root.left,p,q)
    if(p.val>root.val&&q.val>root.val) return lowestCommonAncestor(root.right,p,q)
    else return root
};

11. 剑指 Offer 07. 重建二叉树

在这里插入图片描述

var buildTree = function(preorder, inorder) {
    if(!preorder.length) return null
    let root = new TreeNode(preorder[0])
    let index = inorder.indexOf(preorder[0])
    root.left = buildTree(preorder.slice(1,index+1),inorder.slice(0,index))
    root.right = buildTree(preorder.slice(index+1,preorder.length),inorder.slice(index+1,inorder.length))
    return root
};

12. 剑指 Offer 26. 树的子结构 **

在这里插入图片描述

var isSubStructure = function(A, B) {
    if(!A || !B) return false
    else return helper(A,B)||isSubStructure(A.left,B)||isSubStructure(A.right,B)
};
var helper = function(A,B){
    if(!B) return true
    if(!A) return false
    if(A.val !== B.val) return false
    return helper(A.left,B.left)&&helper(A.right,B.right)
}

13. 剑指 Offer 34. 二叉树中和为某一值的路径 **

在这里插入图片描述

var pathSum = function(root, target) {
    let res = []
    if(!root) return res
    let tmp = []
    let sum = 0
    const helper = function(root,target,sum,tmp){
        tmp.push(root.val)
        sum += root.val
        if(sum === target && !root.left && !root.right){
            res.push(tmp)
        }
        if(root.left) helper(root.left,target,sum,tmp.slice())
        if(root.right) helper(root.right,target,sum,tmp.slice()) 
        return res
    }
    return helper(root,target,sum,tmp)

};

14. 剑指 Offer 37. 序列化二叉树 **

在这里插入图片描述

// An highlighted block
var foo = 'bar';

栈、堆、队列

1. 剑指 Offer 09. 用两个栈实现队列

在这里插入图片描述

var CQueue = function() {
    this.stackA = []
    this.stackB = []
};

/** 
 * @param {number} value
 * @return {void}
 */
 //队尾插入
CQueue.prototype.appendTail = function(value) {
    this.stackA.push(value)
};

/**
 * @return {number}
 */
 //队列头部删除
CQueue.prototype.deleteHead = function() {
    let a = this.stackA.length
    let b = this.stackB.length
    if(!a&&!b) return -1
    else if(b) return this.stackB.pop()
    else{
        while(a>0){
            this.stackB.push(this.stackA.pop())
            a--
        }
        return this.stackB.pop()
    }
};

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

2. 剑指 Offer 30. 包含min函数的栈

在这里插入图片描述

/**
 * initialize your data structure here.
 */
var MinStack = function() {
    this.stack = []
    this.minstack = []
};

/** 
 * @param {number} x
 * @return {void}
 */
MinStack.prototype.push = function(x) {
    this.stack.push(x)
    if(!this.minstack.length) this.minstack.push(x)
    else if(x<=this.minstack[0]) this.minstack.unshift(x)
    else this.minstack.push(x)
};

/**
 * @return {void}
 */
MinStack.prototype.pop = function() {
    let tmp = this.stack.pop()
    if(tmp === this.minstack[0]){
        this.minstack.shift()
    }

};

/**
 * @return {number}
 */
MinStack.prototype.top = function() {
    return this.stack[this.stack.length-1]
};

/**
 * @return {number}
 */
MinStack.prototype.min = function() {
    return this.minstack[0]
};

/**
 * Your MinStack object will be instantiated and called as such:
 * var obj = new MinStack()
 * obj.push(x)
 * obj.pop()
 * var param_3 = obj.top()
 * var param_4 = obj.min()
 */

3. 剑指 Offer 59 - II. 队列的最大值 **没过

在这里插入图片描述


var MaxQueue = function() {
    this.queue = []
    this.maxQueue = []

};

/**
 * @return {number}
 */
MaxQueue.prototype.max_value = function() {
    if(!this.queue.length) return -1
    else return this.maxQueue[0]
};

/** 
 * @param {number} value
 * @return {void}
 */
MaxQueue.prototype.push_back = function(value) {
    this.queue.push(value)
    if(!this.maxQueue.length) this.maxQueue.unshift(value)
    else if(value>=this.maxQueue[0]) this.maxQueue.unshift(value)
    else this.maxQueue.push(value)
};

/**
 * @return {number}
 */
MaxQueue.prototype.pop_front = function() {
    if(!this.queue.length) return -1
    let tmp = this.queue.shift()
    if(tmp === this.maxQueue[0]) this.maxQueue.shift()
    return tmp
};

/**
 * 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()
 */

4. 剑指 Offer 59 - I. 滑动窗口的最大值 **

递归

1. 剑指 Offer 10- II. 青蛙跳台阶问题

在这里插入图片描述

var numWays = function(n) {
    let res =[]
    let MAX = Math.pow(10,9)+7
    res[0] = 1
    res[1] = 1
    for(let i =2;i<=n;i++){
        res[i] = res[i-1] + res[i-2]
        res[i] = res[i]%MAX
    }
    return res[n]
};

2. 剑指 Offer 10- I. 斐波那契数列

// An highlighted block
var fib = function(n) {
    let res = []
    res[0] = 0
    res[1] = 1
    for(let i = 2;i<n+1;i++){
        res[i] = res[i-1] + res[i-2]
        res[i] = res[i] % 1000000007
    }
    return res[n]
};

3. 剑指 Offer 16. 数值的整数次方

在这里插入图片描述

/**
 * @param {number} x
 * @param {number} n
 * @return {number}
 */
var myPow = function(x, n) {
    if(n === 0) return 1
    if(n === 1) return x
    if(n === -1) return 1/x
    if(n%2 === 0){
        let a = myPow(x,n/2)
        return a*a
    }else{
        let b = myPow(x,(n-1)/2)
        return x*b*b
    }
};

动态规划

1. 剑指 Offer 42. 连续子数组的最大和

在这里插入图片描述

/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function(nums) {
    let res = []
    res[0] = nums[0]
    let max = nums[0]
    for(let i=1;i<nums.length;i++){
        let tmp = Math.max(0,res[i-1])+nums[i]
        res.push(tmp)
        max = Math.max(max,tmp)
    }
    return max
};

2. 剑指 Offer 14- I. 剪绳子 **

      var cuttingRope = function (n) {
        if (n === 2) return 1
        if (n === 3) return 2
        if (n > 3) {
          let dp = []
          dp[1] = 1
          dp[2] = 2
          dp[3] = 3
          for (let i = 4; i <= n; i++) {
            dp[i] = 0
            for (let j = 1; j <= n / 2; j++) {
              dp[i] = Math.max(dp[i], dp[j] * dp[i - j])
            }
          }
          console.log(dp)
          return dp[n]
        }
      }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值