问:
- 有一个函数f
- 若它的作用是返回1 ~ 5内的随机数。请加工出可以返回1 ~ 7随机数的函数g;
- 若它的作用是返回a ~ b内的随机数。请加工出可以返回c ~ d随机数的函数g;
- 若它的作用是以p的概率返回0,1-p的概率返回1。请加工出等概率返回0,1的函数g
- 给定一个正整数N,代表二叉树节点个数,请返回它能形成多少种二叉树结构
- 假设有一个字符串,只有'('和')',如果括号是闭合的,比如:'()()()','((()))','(()(()))'。如果不闭合,比如:'())()'。问这个字符串最少需要加多少个字符可以使之闭合。
解: 1.
// 第一问
function f() {
// ...
}
// 首先加工出等概率返回0,1的函数
function getOneOrZero() {
const num = f()
if (num === 3) {
return getOneOrZero()
}
if (num < 3) {
return 0
}
if (num > 3) {
return 1
}
}
// 结果函数
function g() {
// 7可以用3个二进制位表示,所以通过随机返回0,1的函数,生成3个0|1。
// 这是一个0~7的随机数
const res = (getOneOrZero() << 2) + (getOneOrZero() << 1) + getOneOrZero()
// 如果随机到7了,重新随
if (res === 7) {
return g()
}
// 所以res实际上是0~6的随机数
// 返回res+1就是1~7的随机数
return res + 1
}
// 第二问
const a = 5,b = 14,c = 13,d=27
function f() {
// ...
}
// 5 ~ 14 5 6 7 8 9 10 11 12 13 14
// 还是加工出随机返回0,1的函数
function getOneOrZero() {
const num = f()
// 中间数
const mid = (a+b) / 2
// 如果mid是整数,那么随到mid就重来
if (Number.isInteger(mid) && num === mid) {
return getOneOrZero()
}
if (num <= mid) {
return 0
}
if (num > mid) {
return 1
}
}
function g() {
let needBit = 1
// 计算需要多少二进制位
while (2 ** (needBit - 1) < d - c) {
needBit++
}
let res = 0
while (needBit) {
const temp = getOneOrZero()
res += temp << (needBit - 1)
needBit--
}
if (res > d - c){
return g()
}
return res + c
}
// 第三问
// 随两个数,随到0,1和1,0的概率相同,所以这两种情况返回0或者1。其他情况都重新随
function g() {
const num1 = f()
const num2 = f()
if (num1 === 0 && num2 === 1) {
return 1
}
if (num1 === 1 && num2 === 0) {
return 0
}
return g()
}
- 从左子树节点数量分析,它的范围是 0 ~ N-1(相对的,右子树节点数量就是 N - 1 ~ 0)。遍历递归求累加和。
// 递归
function getAllTree(N) {
if (N === 0 || N === 1) return 1
if (N === 2) return 2
let res = 0
// 假设左子树的节点数量从0开始,直到左子树的节点数量变成 N - 1
for (let leftNodes = 0; leftNodes <= N - 1;leftNodes++) {
// 左右子树各自可能性的乘积的累加和
res += getAllTree(leftNodes) * getAllTree(N - 1 - leftNodes)
}
return res
}
// 递归改dp
function getAllTreeDP(N) {
const dp = []
dp[0] = 1
for (let i = 1; i <= N;i++) {
dp[i] = 0
for (let leftNodes = 0; leftNodes < i;leftNodes++) {
dp[i] += dp[leftNodes] * dp[i - 1 - leftNodes]
}
}
return dp[N]
}
- 定义变量count用于统计多余的'('数量,遍历字符串,若碰到'('就增加一次,碰到')'就减少一次。定义变量res用于统计需要匹配的数量,每当减少到-1时,说明有一个')'没有被匹配上,必须添加一个'('用于匹配。所以res增加。当遍历结束后,可能会有多余的'('。所以返回count+res。
function getMinChangeChar(str) {
let count = 0
let res = 0
for (let i = 0; i < str.length; i++) {
if (str[i] === '(') {
count++
}
if (str[i] === ')') {
count--
}
if (count === -1) {
res++
count--
}
}
res += count
return res
}