leetcode刷题记录(8)-简单

1.构造矩形

题目:

作为一位web开发者, 懂得怎样去规划一个页面的尺寸是很重要的。 现给定一个具体的矩形页面面积,你的任务是设计一个长度为 L 和宽度为 W 且满足以下要求的矩形的页面。要求:

1. 你设计的矩形页面必须等于给定的目标面积。

2. 宽度 W 不应大于长度 L,换言之,要求 L >= W 。

3. 长度 L 和宽度 W 之间的差距应当尽可能小。

你需要按顺序输出你设计的页面的长度 L 和宽度 W。

思路:某个数的最大因数,是它的自身平方根(如果这个数是整数的话),所以可以从平方根开始计算。

/**
 * @param {number} area
 * @return {number[]}
 */
var constructRectangle = function(area) {
  let l = ~~Math.sqrt(area, 2);
  while (true) {
    if ((area / l) % 1) {
      l--;
    } else {
      return [area/l,  l];
    }
  }
};

2.下一个更大元素1

题目:

给定两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每个元素在 nums2 中的下一个比其大的值。

nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1 。

思路:首先来个简单的思路。我们先记录在nums2中的每个数以及对应的下标,遍历nums1时,就从这个值对应的下标开始遍历,找到一个比它大的数,如果没有就是-1

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var nextGreaterElement = function(nums1, nums2) {
  const map = new Map();
  const l2 = nums2.length;
  for (let i = 0; i < l2; i++) {
    map.set(nums2[i], i);
  }
  const res = [];
  for (const item of nums1) {
    const start = map.get(item);
    let flag = false;
    for (let j = start + 1; j < l2; j++) {
      if (nums2[j] > item) {
        res.push(nums2[j]);
        flag = true;
        break;
      }
    }
    if (!flag) {
      res.push(-1);
    }
  }
  return res;
};

换一种思路,看一下单调栈的解法。

我们依次取出nums2的元素,利用他们维护一个栈,每次比较栈顶的元素和新加入的元素的大小。如果新加入的元素更大,说明满足要求,就将栈顶的元素出栈,记录此时这个元素以及对应新元素的下标。然后继续比较新的栈顶元素。如果栈顶元素更小,新元素就入栈。遍历完成之后,如果栈内还有元素,说明这些元素后面都没有比他们大的元素,就所有的值对应结果是-1.

然后遍历nums1,依次取对应的结果

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var nextGreaterElement = function(nums1, nums2) {
  const map = new Map();
  const stack = [];
  for (const item of nums2) {
    if (!stack.length) {
      stack.push(item);
    } else {
      while (stack.length) {
        const top = stack.pop();
        if (top > item) {
          stack.push(top,item);
          break;
        } else {
          map.set(top, item);
        }
      }
      if(!stack.length)stack.push(item)
    }
  }
  for (const i of stack) {
    map.set(i, -1);
  }
  return nums1.map((i) => map.get(i));
};

3.键盘行

题目:给定一个单词列表,只返回可以使用在键盘同一行的字母打印出来的单词。键盘如下图所示。

思路:每一行的字母放进同一个字符串,用单词的第一个元素找到是第几行,然后判断该单词的所有元素是否在这一行

/**
 * @param {string[]} words
 * @return {string[]}
 */
var findWords = function(words) {
  const s = ["qwertyuiop", "asdfghjkl", "zxcvbnm"];
  return words.filter((i) => {
    const index = s.findIndex((si) => si.includes(i[0].toLowerCase()));
    return [...i].every((i) => s[index].includes(i.toLowerCase()));
  });
};

4.二叉搜索树中的众数

题目:

给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。

假定 BST 有如下定义:

结点左子树中所含结点的值小于等于当前结点的值
结点右子树中所含结点的值大于等于当前结点的值
左子树和右子树都是二叉搜索树
例如:
给定 BST [1,null,2,2],

   1
    \
     2
    /
   2
返回[2].

提示:如果众数超过1个,不需考虑输出顺序

进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)

思路:先来简单的。遍历二叉树,记录每个数出现的次数以及最大的次数。遍历之后遍历map,找到次数为最大次数的数。

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var findMode = function(root) {
  const map = new Map();
  if (!root) return [];
  const stack = [root];
  let max = 0;
  const res = [];
  while (stack.length) {
    const item = stack.pop();
    const count = (map.get(item.val) || 0) + 1;
    max = max >= count ? max : count;
    map.set(item.val, count);
    if (item.left) {
      stack.push(item.left);
    }
    if (item.right) {
      stack.push(item.right);
    }
  }
  for (const item of map.keys()) {
    if (map.get(item) === max) {
      res.push(item);
    }
  }
  return res;
};

优化:根据二叉搜索树的特性,中序遍历的结果是递增的数组,所以相等的数肯定相邻,记录相邻且相等数的个数即可。每次最大次数更新就清空结果重新记录

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var findMode = function(root) {
    let ans = [], maxCount = 0, count = 0, last = null;
    search(root);
    function search(node) {
        if (node === null) {
            return;
        }
        search(node.left);
        if (last === node.val) {
            count++;
        } else {
            count = 1;
        }
        if (maxCount === count) {
            ans.push(node.val);
        } else if (maxCount < count) {
            ans = [node.val];
            maxCount = count;
        }
        last = node.val;
        search(node.right);
    }
    return ans;
};

5.七进制数

题目:

给定一个整数,将其转化为7进制,并以字符串形式输出。

思路:直接转换或者手动转。手动的话,先确定长度,然后依次计算每个位的数字

/**
 * @param {number} num
 * @return {string}
 */
var convertToBase7 = function(num) {
    return num.toString(7)
};
/**
 * @param {number} num
 * @return {string}
 */
var convertToBase7 = function(num) {
     if (!num) return "0";
  let i = 0,
    res = 1;
  let s = "";
  if (num < 0) {
    num *= -1;
    s = "-";
  }
  while (res <= num) {
    res *= 7;
    i++;
  }
  res /= 7;
  while (i) {
    const v = ~~(num / res);
    s += v;
    num -= v * res;
    i--;
    res /= 7;
  }
  return s;
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值