【算法】括号生成、每日温度

75 阅读3分钟

22、括号生成

0. 题面

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。 示例 1:

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

示例 2:

输入:n = 1
输出:["()"]

提示: ● 1 <= n <= 8

解法

var generateParenthesis = function (n) {
  const result = [];
  const dfs = (lRemain, rRemain, str) => {
    // 左右括号所剩的数量,str是当前构建的字符串
    if (str.length === 2 * n) {
      // 字符串构建完成
      result.push(str); // 加入解集
      return; // 结束当前递归分支
    }
    if (lRemain > 0) {
      // 只要左括号有剩,就可以选它,然后继续做选择(递归)
      dfs(lRemain - 1, rRemain, str + '(');
    }
    if (lRemain < rRemain) {
      // 右括号比左括号剩的多,才能选右括号
      dfs(lRemain, rRemain - 1, str + ')'); // 然后继续做选择(递归)
    }
  };
  dfs(n, n, ''); // 递归的入口,剩余数量都是n,初始字符串是空串
  return result;
};

思路:

  • 递归函数 dfs 的参数是左括号和右括号的剩余数量,以及当前构建的字符串。
  • 当字符串构建完成时,即 str.length === 2 * n 时,加入解集。
  • 选择左括号时,只要 lRemain > 0,就可以选它,然后继续做选择(递归)。
  • 选择右括号时,只要 lRemain < rRemain,才能选右括号,然后继续做选择(递归)。
  • 递归的入口是 dfs(n, n, ''),剩余数量都是 n,初始字符串是空串。

739、每日温度

0. 题面

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

示例 1:

输入: temperatures = [73, 74, 75, 71, 69, 72, 76, 73];
输出: [1, 1, 4, 2, 1, 1, 0, 0];

示例 2:

输入: temperatures = [30, 40, 50, 60];
输出: [1, 1, 1, 0];

示例 3:

输入: temperatures = [30, 60, 90];
输出: [1, 1, 0];

提示:

1. 1 <= temperatures.length <= 10^5
2. 30 <= temperatures[i] <= 100

解法 1

var dailyTemperatures = function (temperatures) {
  const len = temperatures.length;
  const answer = new Array(len);
  for (let i = 0; i < len - 1; i++) {
    const element = temperatures[i];
    const greaterIndex = temperatures.findIndex((item, index) => item > element && index > i);
    answer[i] = greaterIndex === -1 ? 0 : greaterIndex - i;
  }
  answer[len - 1] = 0;
  return answer;
};

思路:

  • 遍历数组,对于每个元素,查找后面第一个比它大的元素的下标,如果找不到则为 0
  • 时间复杂度 O(n^2),空间复杂度 O(n)

解法 2

var dailyTemperatures = function (temperatures) {
  const len = temperatures.length;
  const answer = new Array(len).fill(0);
  const stack = [];
  for (let i = len - 1; i >= 0; i--) {
    while (stack.length && temperatures[i] >= temperatures[stack[stack.length - 1]]) {
      stack.pop();
    }
    if (stack.length) {
      answer[i] = stack[stack.length - 1] - i;
    }
    stack.push(i);
  }
  return answer;
};
  • 优化:可以使用单调栈来优化,
  • 从后往前遍历,维护一个单调递减栈,栈中存放的是下标
  • 如果栈为空,则直接入栈
  • 如果栈不为空,且当前元素大于栈顶元素,则出栈,计算出栈顶元素到当前元素的距离,将结果保存到结果数组中
  • 如果栈不为空,且当前元素小于等于栈顶元素,则入栈
  • 遍历结束后,栈中剩余的元素对应的结果都为 0
  • 时间复杂度 O(n),空间复杂度 O(n)