LeetCode 刷题之路。。。

最近想总结一下自己刷过的leetCode上的题目,只要以简单的为主,用的是js

 

1.657. 机器人能否返回原点

示例 1:

输入: "UD"
输出: true
解释:机器人向上移动一次,然后向下移动一次。所有动作都具有相同的幅度,因此它最终回到它开始的原点。因此,我们返回 true。

思路: 定义一个对象,把UDLR当做key进行存储,最后判断一下UD对应的值是否相等,LR对应的值是否相等

代码:

  var judgeCircle = function(moves) {
    let a = {}
    
    for(let i = 0; i < moves.length; i++) {
        let key = moves[i]
        if(key in a) {
            Object.assign(a, {}, {[key]: a[key] + 1})
        } else {
            Object.assign(a, {}, {[key]: 1})
        }
    }
        
    if(a.L === a.R && a.D === a.U)
        return true
    
    return false    
};

 

2. 637. 二叉树的层平均值

给定一个非空二叉树, 返回一个由每层节点平均值组成的数组.

示例 1:

输入:
    3
   / \
  9  20
    /  \
   15   7
输出: [3, 14.5, 11]
解释:
第0层的平均值是 3,  第1层是 14.5, 第2层是 11. 因此返回 [3, 14.5, 11].

 

思路: 定义一个中间变量,存储同一层的数

 

第一种.  通过size控制在同一层,然后用_queue暂时存储同层节点

var averageOfLevels = function(root) {
    let res = []
    let queue = [root]
    if(!root)
        return []    
     while(queue.length) {
         let len = queue.length
         let size = queue.length
         let count = 0
         let node = null
         let _queue = []
         while(size > 0) {           //  如果size大于0,说明同层的数还没加完
             node = queue.shift()  //  从queue头部删除
             if(node.left) _queue.push(node.left)  // 用_queue存储同层的节点 
             if(node.right) _queue.push(node.right)
             count += node.val      // 计算某一层的总和
             size--                         
         }
         queue = _queue           // 把下一层节点赋给queue
         res.push(count / len)    // 计算该层的平均值
     }    
    return res
};

第二种. 直接用数组遍历

var averageOfLevels = function(root) {
    let res = []
    let queue = [root]
    if(!root)
        return []
     while(queue.length) {
        let len = queue.length
        let count = 0
        let _queue = []   // 用使用_queue暂时存储同一层的节点
        queue.forEach(item => {    // 遍历queue,计算当前层的总数
            if(item.left) _queue.push(item.left)   // 获取下一层的所有节点
            if(item.right) _queue.push(item.right)
            count += item.val
        })
        queue = _queue 
        res.push(count / len)
    }    
    return res
};

 

3. 104. 二叉树的最大深度

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:
给定二叉树 [3,9,20,null,null,15,7]

    3
   / \
  9  20
    /  \
   15   7

返回它的最大深度 3 

思路:最简单的就是用递归,直接上代码:

var maxDepth = function(root) {
    if(!root)
        return 0
    return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)) // 取左右结点中最长的,不断递归下去,直到结点为空(熟悉递归的人应该一下子就看懂了)
};

 

4. 617. 合并二叉树

示例 1:

输入: 
	Tree 1                     Tree 2                  
          1                         2                             
         / \                       / \                            
        3   2                     1   3                        
       /                           \   \                      
      5                             4   7                  
输出: 
合并后的树:
	     3
	    / \
	   4   5
	  / \   \ 
	 5   4   7

思路:还是用递归,记住一点,当结点为空时,返回另外一个结点,如果都不为空,那么两个结点相加

var mergeTrees = function(t1, t2) {
    if(!t1) return t2   // t1为空只需返回t2就ok了
    if(!t2) return t1
    
    t1.val += t2.val   // 如果都不为空,那么两个结点相加
    t1.right = mergeTrees(t1.right, t2.right)  // 继续遍历t1的右结点
    t1.left = mergeTrees(t1.left, t2.left)
    return t1
};

 

5.  237. 删除链表中的节点

示例 1:

输入: head = [4,5,1,9], node = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} node
 * @return {void} Do not return anything, modify node in-place instead.
 */

思路:这题其实有点奇怪,输入只有要删除的结点,并没有链表的头,但其实很简单(注意这里的node不是整型,是链表里的结点)

var deleteNode = function(node) {
    node.val = node.next.val    // 直接把node的后一个结点值赋给node
    node.next = node.next.next  // 然后删除node的后一个结点,这样就ok了
};

 

6.  226. 翻转二叉树

示例:

输入:

     4
   /   \
  2     7
 / \   / \
1   3 6   9

输出:

     4
   /   \
  7     2
 / \   / \
9   6 3   1

思路:还是用递归。。。,好像二叉树的题目基本上都是用递归解决的

var invertTree = function(root) { 
    if(root === null)
        return null;
    invertTree(root.left); // 一直往里面递,直到结点为空
    invertTree(root.right);
    [root.left, root.right] = [root.right, root.left]; // 为空后交换左右结点,这里会形成一个从下往上从左到右的交换过程,emmm差不多就是这样了
    return root;  
};

 

7.  344. 反转字符串

编写一个函数,其作用是将输入的字符串反转过来。

示例 1:

输入: "hello"
输出: "olleh"

这题很简单,提供一个比较优雅的写法

var reverseString = function(s) {
    return [...s].reverse().join('')
};

... 会把string类型的s解构成数组

 

8. 700. 二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。

例如,

给定二叉搜索树:

        4
       / \
      2   7
     / \
    1   3

和值: 2

你应该返回如下子树:

      2     
     / \   
    1   3

思路: 还是递归,其实就是遍历二叉树,碰到大的继续遍历右子树,小的继续遍历左子树

var searchBST = function(root, val) {
    if(root === null)
        return root
    
    if(root.val > val) 
        return searchBST(root.left, val)
    else if(root.val < val)
        return searchBST(root.right, val)
    else 
        return root
};

 

9.再来道简单的题  557. 反转字符串中的单词 III

给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

示例 1:

输入: "Let's take LeetCode contest"
输出: "s'teL ekat edoCteeL tsetnoc" 

思路:很简单,直接上代码

var reverseWords = function(s) {
    let arr = s.split(' ') // 先转成数组
    let ans = ''
    for(let i = 0; i < arr.length; i++) {
        ans += [...arr[i]].reverse().join('') + ' ' // 这里要再转一次把arr[i]转成数组,调用reverse方法进行反转
    }
    return ans.substr(0, ans.length - 1)
};

另外一种比较优雅的写法

var reverseWords = function(s) {

   return s.split(' ').map(item => item.split('').reverse().join('')).join(' ')  // 思路其实和上面的差不多

};

你可能感兴趣的:(LeetCode)