JS算法之括号生成及下一个排列

553 阅读2分钟

这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战

括号生成

Hot100 22.括号生成

难度:中等

题目:leetcode-cn.com/problems/ge…

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

有效括号组合需满足:左括号必须以正确的顺序闭合。

示例1:

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

示例2:

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

提示:1 <= n <= 8

题解

回溯法

正确的括号需要满足两个条件:

  • 左括号小于n
  • 添加右括号时,左括号数量必须大于右括号数量,并且右括号小于n
 /**
  * @param {number} n
  * @return {string[]}
  */
 var generateParenthesis = function(n) {
   let res = [];
   
   const helper = (left, right, s) => {
     if(left === n && right === n) {
       return res.push(s);
     }
     if(left < n) helper(left+1,right,s+'(');
     if(right < left) helper(left,right+1,s+')');
   }
   helper(0,0,'')
   return res;
 };
  • 时间复杂度:??
  • 空间复杂度:O(n)

下一个排列

Hot100 31.下一个排列

难度:中等

题目:leetcode-cn.com/problems/ne…

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列(即,组合出下一个更大的整数)。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

示例 1:

 输入:nums = [1,2,3]
 输出:[1,3,2]

示例 2:

 输入:nums = [3,2,1]
 输出:[1,2,3]

示例 3:

 输入:nums = [1,1,5]
 输出:[1,5,1]

示例 4:

 输入:nums = [1]
 输出:[1]

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 100

题解

题干的意思是:找出这个数组排序出的所有数中,刚好比当前数大的那个数

比如当前 nums = [1,2,3]。这个数是123,找出1,2,3这3个数字排序可能的所有数,排序后,比123大的那个数,也就是132

如果当前 nums = [3,2,1]。这就是1,2,3所有排序中最大的那个数,那么就返回1,2,3排序后所有数中最小的那个,也就是1,2,3 -> [1,2,3]

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var nextPermutation = function (nums) {
    // 为了找更大的下一个数字
    // 1、需要将左边的小数和右边的大数交换
    // 2、然后将交换完的大数后改成升序

    // 找小数
    let left = 0, temp = 0
    for (let i = nums.length - 1; i > 0; i--) {
        if (nums[i] > nums[i - 1]) {
            left = i - 1
            temp = i
            break
        }
    }
    // 找大数(因为temp后面都是递减的)
    let right = 0
    for (let i = nums.length - 1; i >= temp; i--) {
        if (nums[i] > nums[left]) {
            right = i
            break
        }
    }
    // 交换
    let a = nums[left]
    nums[left] = nums[right]
    nums[right] = a
    // 交换完之后把temp到最后升序(直接取反)
    // nums = nums.slice(0, temp).concat(nums.slice(temp).reverse())
    for (let i = temp; i < temp + Math.floor((nums.length - temp) / 2); i++) {
        let p = nums[i]
        nums[i] = nums[temp + nums.length - i - 1]
        nums[temp + nums.length - i - 1] = p
    }
};