数据结构与算法解题-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))

在这里插入图片描述

评论 44
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码敲到头发茂密

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值