leetcode刷题记录(6)-简单

1.路径总和 III

题目:

给定一个二叉树,它的每个结点都存放着一个整数值。

找出路径和等于给定数值的路径总数。

路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。

思路:首先,要计算得到某两个父子节点路径上的值的总和,要明确一点,路径之和,等于根节点到子节点(包括子节点)的值的总和,与根节点到父节点(不含父节点)的值的总和的差。

然后,在遍历的时候,每遍历一个节点,则记录根节点到这个节点的值的和。

为了防止重复计算,我们可以在遍历节点的时候,只计算从以这个节点为结束节点的路径

/**
 * @param {TreeNode} root
 * @param {number} sum
 * @return {number}
 */
var pathSum = function (root, sum) {
  if (!root) return 0;
  let res = 0;
  const stack = [
    {
      val: [0],
      node: root,
    },
  ];
  while (stack.length) {
    const item = stack.shift();
    const preVal = item.val[item.val.length - 1];
    for (const val of item.val) {
      if (preVal + item.node.val - val === sum) {
        res++;
      }
    }
    if (item.node.left) {
      stack.push({
        val: item.val.concat([preVal + item.node.val]),
        node: item.node.left,
      });
    }
    if (item.node.right) {
      stack.push({
        val: item.val.concat([preVal + item.node.val]),
        node: item.node.right,
      });
    }
  }
  return res;
};

2.排列硬币

题目:

你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。

给定一个数字 n,找出可形成完整阶梯行的总行数。

n 是一个非负整数,并且在32位有符号整型的范围内。

思路:等差数列的和,n行的等差数列,和为(1+n)*n/2,所以直接数学计算

/**
 * @param {number} n
 * @return {number}
 */
var arrangeCoins = function(n) {
return ~~((Math.sqrt(1+8*n,2)-1)/2)
};

迭代也可

/**
 * @param {number} n
 * @return {number}
 */
var arrangeCoins = function(n) {
    let i=0;
    while(n>i){
        i++
        n-=i
    }
    return i
};

3.压缩字符串

题目:

给定一个范围在  1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。

找到所有在 [1, n] 范围之间没有出现在数组中的数字。

您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。

思路:原地算法,不使用额外的空间的话,我们可以遍历一个数字,就给这个数字的值-1下标上的值乘以-1,这样,通过下标,我们就知道有哪些值。第二次遍历,正数值的下标就是没出现过的数

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var findDisappearedNumbers = function(nums) {
  const l = nums.length;
  const res = [];
  if (!l) return res;
  for (const item of nums) {
    const v = Math.abs(item);
    if (nums[v - 1] > 0) {
      nums[v - 1] *= -1;
    }
  }
  for (let i = 0; i < l; i++) {
    if (nums[i] > 0) {
      res.push(i + 1);
    }
  }
  return res;
};

4.最小移动次数是数组元素相等

题目:给定一个长度为 n 的非空整数数组,找到让数组所有元素相等的最小移动次数。每次移动将会使 n - 1 个元素增加 1。

思路:移动一次,其他元素+1,自己不变,其实就是变相的自己-1.所以,只需要计算每个数和最小数的差即可

/**
 * @param {number[]} nums
 * @return {number}
 */
var minMoves = function(nums) {
  const l = nums.length;
  if (!l) return 0;
  let res = 0;
  let min = nums[0];
  for (let i = 1; i < l; i++) {
    res += nums[i] - nums[0];
    min = min < nums[i] ? min : nums[i];
  }
  return res + (nums[0] - min) * l;
};
/**
 * @param {number[]} nums
 * @return {number}
 */
var minMoves = function(nums) {
  const l = nums.length;
  if (!l) return 0;
  let res = 0;
  nums.sort((a, b) => a - b);
  for (let i = 1; i < l; i++) {
    res += nums[i] - nums[0];
  }
  return res;
};

5.分发饼干

题目:

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有一个尺寸 sj 。如果 sj >= gi ,我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

注意:

你可以假设胃口值为正。
一个小朋友最多只能拥有一块饼干。

思路:先排序,然后双指针。

/**
 * @param {number[]} g
 * @param {number[]} s
 * @return {number}
 */
var findContentChildren = function(g, s) {
  g.sort((a, b) => a - b);
  s.sort((a, b) => a - b);
  let i = 0;
  let j = 0;
  let l1 = g.length;
  let l2 = s.length;
  let res = 0;
  while (i < l1 && j < l2) {
    if (g[i] <= s[j]) {
      res++;
      i++
    }
    j++;
  }
  return res;
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值