数据结构与算法解题-20240424
一、20. 有效的括号
简单
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
示例 1:
输入:s = “()”
输出:true
示例 2:
输入:s = “()[]{}”
输出:true
示例 3:
输入:s = “(]”
输出:false
class S20:
def func(self,s):
if len(s)%2==1:
return False
dic={
")":"(",
"]":"[",
"}":"{"
}
stack=[]
for i in s:
if i not in dic:
stack.append(i)
elif not stack or dic[i]!=stack.pop():
return False
return len(stack)==0
r=S20()
s='()'
s='()[]{}'
s='(}'
print(r.func(s))
二、LCP 06. 拿硬币
简单
桌上有 n 堆力扣币,每堆的数量保存在数组 coins 中。我们每次可以选择任意一堆,拿走其中的一枚或者两枚,求拿完所有力扣币的最少次数。
示例 1:
输入:[4,2,1]
输出:4
解释:第一堆力扣币最少需要拿 2 次,第二堆最少需要拿 1 次,第三堆最少需要拿 1 次,总共 4 次即可拿完。
示例 2:
输入:[2,3,10]
输出:8
思路
直接遍历计算每堆硬币 → 每堆硬币数量 // 2 向上取整 → 求和 → 返回
class Solution(object):
def minCount(self, coins):
return sum((x + 1) // 2 for x in coins)
三、441. 排列硬币
简单
你总共有 n 枚硬币,并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯,其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。
给你一个数字 n ,计算并返回可形成 完整阶梯行 的总行数。
思路
数学推导
根据排序硬币规则,可以得知每一 level 所放硬币数等于所在阶梯层数:
level 1: 1
level 2: 2
level 3: 3
level l:l 需要的硬币总数, 找出规律:
level 1: 1
level 2: 3
level 3: 6
level 4: 10 …
根据以上规律可以得知,每递增一层,需要的硬币总数等于放满当前层之前的所有阶梯所需要的硬币总数加上当前的阶梯层数
level 1: 1 * (1 + 1) / 2
level 2: 2 * (2 + 1) / 2
level 3: 3 * (3 + 1) / 2
level n: l * (l + 1) / 2
需要的硬币总数,可以用下列公式得到: level(n)=l∗(l+1)/2
构成i行阶梯,需要(1+i)*i/2个硬币
class S441:
def func(self,n):
left=1
right=n
while left<=right:
mid=(left+right)//2
if mid*(1+mid)/2<n:
left=mid+1
else:
right=mid-1
return right
r=S441()
n=8
print(r.func(n))
四、374. 猜数字大小
简单
猜数字游戏的规则如下:
每轮游戏,我都会从 1 到 n 随机选择一个数字。 请你猜选出的是哪个数字。
如果你猜错了,我会告诉你,你猜测的数字比我选出的数字是大了还是小了。
你可以通过调用一个预先定义好的接口 int guess(int num) 来获取猜测结果,返回值一共有 3 种可能的情况(-1,1 或 0):
-1:我选出的数字比你猜的数字小 pick < num
1:我选出的数字比你猜的数字大 pick > num
0:我选出的数字和你猜的数字一样。恭喜!你猜对了!pick == num
返回我选出的数字。
示例 1:
输入:n = 10, pick = 6
输出:6
示例 2:
输入:n = 1, pick = 1
输出:1
示例 3:
输入:n = 2, pick = 1
输出:1
示例 4:
输入:n = 2, pick = 2
输出:2
思路:二分查找
def guessNumber(n):
left=1
right=n
while left<=right:
mid=(left+right)//2
ret=guess(mid)
if ret==0:
return mid
elif ret==-1:
right=mid-1
else:
left=mid+1
五、377. 组合总和 Ⅳ
中等
给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。
题目数据保证答案符合 32 位整数范围。
示例 1:
输入:nums = [1,2,3], target = 4
输出:7
解释:
所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
请注意,顺序不同的序列被视作不同的组合。
示例 2:
输入:nums = [9], target = 3
输出:0
class S377:
def func(self, nums, target):
res = []
def dfs(path, total):
if total == target:
res.append(path[:])
return
for i in range(len(nums)):
if total + nums[i] > target:
continue
total += nums[i]
path.append(nums[i])
dfs(path, total)
total -= nums[i]
path.pop()
dfs([], 0)
return res
r = S377()
nums = [9]
target = 3
print(r.func(nums, target))