LeetCode2022 8月 每日一题
Posted woodwhale
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode2022 8月 每日一题相关的知识,希望对你有一定的参考价值。
【LeetCode】2022 8月 每日一题
8.1 生成每种字符都是奇数个的字符串
题目
给你一个整数 n,请你返回一个含 n 个字符的字符串,其中每种字符在该字符串中都恰好出现 奇数次 。
返回的字符串必须只含小写英文字母。如果存在多个满足题目要求的字符串,则返回其中任意一个即可。
思路
纯纯的简单题,偶数字符串就是奇数 + 1的形式,奇数字符串,直接返回这个奇数*a
代码
function generateTheString(n: number): string
let res = new Array<string>(n-1).fill('a').join('')
return n % 2 == 0 ? res + 'b' : res + 'a'
8.2 设计循环队列
题目
思路
循环队列就完事了,数据结构课还用c写过
代码
class MyCircularQueue
que: number[]
s: number // 队首
e: number // 队尾
l: number // 队列最大长度
cnt: number // 目前队列长度
constructor(k: number)
this.que = new Array(k)
this.l = k
this.s = 0
this.e = 0
this.cnt = 0
enQueue(value: number): boolean
if (this.cnt == this.l) return false
this.que[this.e] = value
this.e = (this.e + 1) % this.l
this.cnt++
return true
deQueue(): boolean
if (this.cnt == 0) return false
this.s = (this.s + 1) % this.l
this.cnt--
return true
Front(): number
if (this.cnt == 0) return -1
return this.que[this.s]
Rear(): number
if (this.cnt == 0) return -1
return this.que[(this.e - 1 + this.l) % this.l]
isEmpty(): boolean
return this.cnt == 0
isFull(): boolean
return this.cnt == this.l
8.3 有序队列
题目
给定一个字符串 s 和一个整数 k 。你可以从 s 的前 k 个字母中选择一个,并把它加到字符串的末尾。
返回 在应用上述步骤的任意数量的移动后,字典上最小的字符串 。
思路
k = 1,只能换一个字母,暴力遍历比较一次
k > 1,直接返回字典序最小的(因为k只要>=2就能实现冒泡排序)
代码
function orderlyQueue(s: string, k: number): string
const fun = (s: string) =>
let n = s
for (let i = 1; i < s.length; i++)
if (s[i] > n[0]) continue
let nn = s.substr(i) + s.substr(0,i)
if (n > nn)
n = nn
return n
return k == 1 ? fun(s) : s.split("").sort().join("")
;
8.4 非递增顺序的最小子序列
题目
思路
先遍历一次数组,算出所有元素的sum
逆序排序数组
从前向后遍历新数组,加起来的tmpSum > sum - tmpSum就行
代码
function minSubsequence(nums: number[]): number[]
let sum = 0
nums.forEach(item => sum += item)
nums.sort((a,b) => b-a)
let res = []
let tmp = 0
for (let it of nums)
tmp += it
res.push(it)
if (tmp > sum - tmp)
return res
return res
8.5 在二叉树中增加一行
题目
思路
层序遍历,遍历到depth-1层就给他加上新的一层
代码
function addOneRow(root: TreeNode | null, val: number, depth: number): TreeNode | null
if (root == null)
return null
if (depth == 1)
return new TreeNode(val,root)
let res = root
let curRow = 0
let que = []
que.push(root)
while (que.length != 0)
curRow++
let len = que.length // 先把目前队列长度给定死,不然下面的for循环会改变
for (let i = 0; i < len; i++)
let node = que.shift()
if (node.left != null)
que.push(node.left)
if (node.right != null)
que.push(node.right)
if (curRow == depth - 1)
node.left = new TreeNode(val,node.left)
node.right = new TreeNode(val, null, node.right)
return res
8.6 数组中的字符串匹配
题目
思路
直接按长度降序,遍历前面的加入tmp字符串中,查看当前遍历的str是否在tmp字符串中
代码
function stringMatching(words: string[]): string[]
words.sort((a, b) => b.length - a.length) // 按长度排序,长的在前面
console.log(words)
let curConcat = ''
let res = []
for (let word of words)
if (curConcat.indexOf(word) !== -1)
res.push(word)
curConcat += word + " "
return res
8.7 函数的独占时间
题目
思路
直接栈模拟即可,单线程,会挤占,梦回操作系统的作业调度
代码
function exclusiveTime(n: number, logs: string[]): number[]
let stack = []
let res = new Array<number>(n)
res.fill(0)
logs.forEach(log =>
let taskId = parseInt(log.split(":")[0])
let cmd = log.split(":")[1]
let time = parseInt(log.split(":")[2])
if (cmd[0] == 's')
// 开始执行,查看stack中是否未空
if (stack.length != 0)
let preId = stack[stack.length-1].taskId
let preTime = stack[stack.length-1].time
res[preId] += time - preTime
stack.push(
taskId: taskId,
time: time
)
else
// 结束执行,判断stack是否未空
let data = stack.pop()
res[taskId] += time - data.time + 1
if (stack.length != 0)
// 更新栈顶的任务时间
stack[stack.length - 1].time = time + 1
)
return res
8.8 特殊的二进制序列
题目
特殊的二进制序列是具有以下两个性质的二进制序列:
- 0 的数量与 1 的数量相等。
- 二进制序列的每一个前缀码中 1 的数量要大于等于 0 的数量。
给定一个特殊的二进制序列 S
,以字符串形式表示。定义一个操作 为首先选择 S
的两个连续且非空的特殊的子串,然后将它们交换。(两个子串为连续的当且仅当第一个子串的最后一个字符恰好为第二个子串的第一个字符的前一个字符。)
在任意次数的操作之后,交换后的字符串按照字典序排列的最大的结果是什么?
示例 1:
输入: S = "11011000"
输出: "11100100"
解释:
将子串 "10" (在S[1]出现) 和 "1100" (在S[3]出现)进行交换。
这是在进行若干次操作后按字典序排列最大的结果。
说明:
S
的长度不超过50
。S
保证为一个满足上述定义的特殊 的二进制序列。
思路
是我可以做的困难题。
首先如何理解特殊序列二进制数?把1当作(
,把0当作)
,0和1成对出现,同时1永远在0前面,同时1的数量和0的数量一致。如果比作括号,那么就是,左括号一定在右括号的前面,同时括号是成对出现的。
如果对于一个字符串进行无限拆分,直到拆成了题目所需要的特殊的二进制字符串的形式,那么必然是1 ?? 0
的形式,这里的??
也是遵守上述括号原则的
那么直接递归求解,首先给一个空的list,递归字符串,每次找到当前字符串可以拆分的形式,加入到list中
最终的list里面存储的就是所有的特殊的二进制序列,对这个list进行排序,1开头的一定是在前面的(字典序最大),直接降序输出就行了
代码
function makeLargestSpecial(s: string): string
let list: string[] = [] // 存放有效的特殊二进制序列
let len: number = s.length
let cur: number = 0
let socre: number = 0
for (let i = 0; i < len; i++)
socre += s[i] == "1" ? 1 : -1
if (socre == 0)
// 等于0表示是有效的一对二进制序列
list.push("1" + makeLargestSpecial(s.substring(cur + 1, i)) + "0")
cur = i + 1
list.sort((a: string,b: string) => b.localeCompare(a)) // 1在前面的肯定比0在前面的大,其实是比较 b+a 和 a+b
return list.join("")
8.9 逐步求和得到正数的最小值
题目
给你一个整数数组 nums
。你可以选定任意的 正数 startValue 作为初始值。
你需要从左到右遍历 nums
数组,并将 startValue 依次累加上 nums
数组中的值。
请你在确保累加和始终大于等于 1 的前提下,选出一个最小的 正数 作为 startValue 。
示例 1:
输入:nums = [-3,2,-3,4,2]
输出:5
解释:如果你选择 startValue = 4,在第三次累加时,和小于 1 。
累加求和
startValue = 4 | startValue = 5 | nums
(4 -3 ) = 1 | (5 -3 ) = 2 | -3
(1 +2 ) = 3 | (2 +2 ) = 4 | 2
(3 -3 ) = 0 | (4 -3 ) = 1 | -3
(0 +4 ) = 4 | (1 +4 ) = 5 | 4
(4 +2 ) = 6 | (5 +2 ) = 7 | 2
示例 2:
输入:nums = [1,2]
输出:1
解释:最小的 startValue 需要是正数。
示例 3:
输入:nums = [1,-2,-3]
输出:5
提示:
1 <= nums.length <= 100
-100 <= nums[i] <= 100
思路
前缀和即可
代码
我直接是暴力求解,其实可以在算前缀和的时候就计算,懒得动脑子
function minStartValue(nums: number[]): number
let len = nums.length
const sum = []
let s = 0
for (let num of nums)
s += num
sum.push(s)
let min = 101
sum.forEach(it =>
if (it < min)
min = it
)
return min < 0 ? -(min-1) : 1
8.10 求解方程
题目
求解一个给定的方程,将x
以字符串 "x=#value"
的形式返回。该方程仅包含 '+'
, '-'
操作,变量 x
和其对应系数。
如果方程没有解,请返回 "No solution"
。如果方程有无限解,则返回 “Infinite solutions”
。
如果方程中只有一个解,要保证返回值 ‘x’ 是一个整数。
示例 1:
输入: equation = "x+5-3+x=6+x-2"
输出: "x=2"
示例 2:
输入: equation = "x=x"
输出: "Infinite solutions"
示例 3:
输入: equation = "2x=x"
输出: "x=0"
提示:
3 <= equation.length <= 1000
equation
只有一个'='
.equation
方程由整数组成,其绝对值在[0, 100]
范围内,不含前导零和变量'x'
。
思路
模拟即可,需要注意有很特殊的用例0x=0
之类的
代码
const NO = "No solution"
const INF = "Infinite solutions"
function solveEquation(equation: string): string
let [left, right] = equation.split("=")
let leftX = 0, leftInt = 0, rightX = 0, rightInt = 0
let curSign = left[0] == '-' ? -1 : 1
let curInt = 0
for (let i = 0; i < left.length; i++)
if (left[i] == '+')
leftInt += curInt * curSign
curInt = 0
curSign = 1
else if (left[i] == '-')
leftInt += curInt * curSign
curInt = 0
curSign = -1
else if (left[i] == 'x')
if (i > 0 && left[i - 1] == '0') continue
leftX += (curSign * curInt) == 0 ? curSign : (curSign * curInt)
curInt = 0
else if (left[i] >= '0' && left[i] <= '9')
curInt = curInt * 10 + parseInt(left[i])
if (i == left.length - 1 && curInt != 0)
leftInt += curInt * curSign
curSign = right[0] == '-' ? -1 : 1
curInt = 0
for (let i = 0; i < right.length; i++)
if (right[i] == '+')
rightInt += curInt * curSign
curInt = 0
curSign = 1
else if (right[i] == '-')
rightInt += curInt * curSign
curInt = 0
curSign = -1
else if (right[i] == 'x')
if (i > 0 && right[i - 1] == '0') continue
rightX += (curSign * curInt) == 0 ? curSign : (curSign * curInt)
curInt = 0
else if (right[i] >= '0' && right[i] <= '9')
curInt = curInt * 10 + parseInt(right[i])
if (i == right.length - 1 && curInt != 0)
rightInt += curInt * curSign
// console.log(leftX,le以上是关于LeetCode2022 8月 每日一题的主要内容,如果未能解决你的问题,请参考以下文章