这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战
括号生成
Hot100 22.括号生成
难度:中等
数字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.下一个排列
难度:中等
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列(即,组合出下一个更大的整数)。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
示例 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
}
};