js解leetcode(55)-简单

本文介绍了四种常见的二叉树操作:1. 二叉树的镜像,通过递归和迭代实现左右节点互换;2. 对称二叉树的判断,通过比较镜像位置节点的对称性;3. 从上到下打印二叉树的层次遍历,采用递归和迭代方法;4. 数组中出现次数超过一半的数字查找,利用投票算法;5. 找出数组中最小的k个数,使用排序和递归快排方法。这些算法深入浅出,有助于理解二叉树和数组处理的基本思路。
摘要由CSDN通过智能技术生成

1.二叉树的镜像

题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。

思路:镜像,就是左节点变右节点,右节点变左节点。递归或者迭代均可

递归:

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {TreeNode}
 */
var mirrorTree = function(root) {
  if (!root) return root;
  [root.left, root.right] = [mirrorTree(root.right), mirrorTree(root.left)];
  return root;
};

迭代:

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {TreeNode}
 */
var mirrorTree = function(root) {
  if (!root) return root;
    const stack=[root]
    while(stack.length){
        const item=stack.shift()
        if(!item)continue
        [item.left,item.right]=[item.right,item.left]
        stack.push(item.left,item.right)
    }
    return root
};

2.对称二叉树

题目:

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

思路:和上一题类似,判断镜像位置上的节点是否对撑即可

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isSymmetric = function(root) {
  if (!root) return true
  let queue = [root.left, root.right]
  while (queue.length) {
    let t1 = queue.shift(), t2 = queue.shift()
    if (t1 === null && t2 === null) continue
    if (t1 === null || t2 === null || t1.val != t2.val) return false
    queue.push(t1.left, t2.right, t1.right, t2.left)
  }
  return true
};

3.从上到下打印二叉树

题目:从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

思路:二叉树的层序遍历。递归和迭代均可

递归:

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrder = function(root) {
  if (!root) return [];
  const stack = [];
  const search = (root, level = 0) => {
    if (!root) return;
    if (stack[level]) {
      stack[level].push(root.val);
    } else {
      stack[level] = [root.val];
    }
    search(root.left, level + 1);
    search(root.right, level + 1);
  };
  search(root);
  return stack;
};

迭代:

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrder = function(root) {
  if (!root) return [];
  let stack = [root];
    const res=[];
    while(stack.length){
        const temp=[]
        const v=[]
        for(const item of stack){
            if(!item)continue
            temp.push(item.val)
            item.left&&v.push(item.left)
            item.right&&v.push(item.right)
        }
    temp.length&&res.push(temp)
    stack=v
    }
  return res;
};

4.数组中出现次数超过一半的数字

题目:

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

 

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

思路:投票算法

/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
  let c = 0;
  let v = NaN;
  for (const n of nums) {
    if (!c) {
      v = n;
      c++;
    } else if (v == n) {
      c++;
    } else {
      c--;
    }
  }
  return v;
};

5.最小的K个数

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

思路:简单的解法是排序

时间复杂度O(nlogn),空间复杂度O(1)

/**
 * @param {number[]} arr
 * @param {number} k
 * @return {number[]}
 */
var getLeastNumbers = function(arr, k) {
  const res = [];
  for (const item of arr) {
    const l = res.length;
    if (!l) {
      res.push(item);
      continue;
    }
    let i = 0;
    for (; i < l; i++) {
      if (res[i] > item) break;
    }
    res.splice(i, 0, item);
  }
  return res.slice(0, k);
};

也可以用递归的快排完成,不过快排不需要完全排序。

快排的思路,是随机选一数(一般是中间位置的数),小于的放入左边,大于的放入右边。

所以,如果k与左边的数组长度相等,那么结果就是左边的数组,如果小于,递归求解左边数组;如果大于,则记录左边的子数组长度l,并更新k的值为k-l-1(多减一个1是因为选的基数也含在内),递归求解右边数组

时间复杂度O(n),空间复杂度O(1)

/**
 * @param {number[]} arr
 * @param {number} k
 * @return {number[]}
 */
var getLeastNumbers = function(arr, k, pre = []) {
  if (!k) return pre;
  const l = arr.length;
if(k===l)return pre.concat(arr)
  const mid = ~~(l / 2);
  let left = [];
  let right = [];
  for (let i = 0; i < l; i++) {
    if (i == mid) continue;
    if (arr[i] <= arr[mid]) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  if (k == left.length) return pre.concat(left);
  if (k == left.length + 1) return pre.concat(left, arr[mid]);
  if (k > left.length)
    return getLeastNumbers(
      right,
      k - left.length - 1,
      pre.concat(left, arr[mid])
    );
  return getLeastNumbers(left, k, pre);
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值