[leetcode] Python(31)--第K个语法符号(779)、不同的二叉搜索树 II(95)、根据字符出现频率排序(451)、三数之和(15)

从零开始的力扣(第三十一天)~

1.第K个语法符号

在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。

给定行数 N 和序数 K,返回第 N 行中第 K个字符。(K从1开始)

例子:

输入: N = 1, K = 1
输出: 0

输入: N = 2, K = 1
输出: 0

输入: N = 2, K = 2
输出: 1

输入: N = 4, K = 5
输出: 1

解释:
第一行: 0
第二行: 01
第三行: 0110
第四行: 01101001

注意:

N 的范围 [1, 30].
K 的范围 [1, 2^(N-1)].
—————————————————————————————————————————

递归查找,无难度
class Solution:
    def kthGrammar(self, N: int, K: int) -> int:
        if N == 1:
            return 0
        if K % 2 == 1:
            return 0 if self.kthGrammar(N - 1, (K + 1) // 2) == 0 else 1
        else:
            return 1 if self.kthGrammar(N - 1, K // 2) == 0 else 0

2.不同的二叉搜索树 II

给定一个整数 n,生成所有由 1 … n 为节点所组成的二叉搜索树。

示例:
输入: 3
输出:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
解释:
以上的输出对应以下 5 种不同结构的二叉搜索树:

—————————————————————————————————————————

这道题的解法有点难想,使用递归,二叉搜索树就是左子树都比根小,右子树都比根大,以这个为前提分配左右子树,再递归内子树
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def generateTrees(self, n: int) -> List[TreeNode]:
        def helper(tree):
            # tree 为有序数组
            ans = []
            # 遍历可能的根结点
            for i, val in enumerate(tree):
                # left、right 分别为左右子树包含的结点
                left, right = tree[:i], tree[i+1:]
                # 若左子树为 NULL,则令其为 [None]
                for ltree in helper(left) or [None]:
                    # 若右子树为 NULL,则令其为 [None]
                    for rtree in helper(right) or [None]:
                        root = TreeNode(val)
                        root.left, root.right = ltree, rtree
                        ans.append(root)
            return ans
        return helper(range(1, n+1))

3.根据字符出现频率排序

给定一个字符串,请将字符串里的字符按照出现的频率降序排列。

示例 1:
输入:
“tree”

输出:
“eert”

解释:
'e’出现两次,'r’和’t’都只出现一次。
因此’e’必须出现在’r’和’t’之前。此外,"eetr"也是一个有效的答案。

示例 2:
输入:
“cccaaa”

输出:
“cccaaa”

解释:
'c’和’a’都出现三次。此外,"aaaccc"也是有效的答案。
注意"cacaca"是不正确的,因为相同的字母必须放在一起。
示例 3:

输入:
“Aabb”

输出:
“bbAa”

解释:
此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。
注意’A’和’a’被认为是两种不同的字符。
—————————————————————————————————————————

先用字典储存个数,最后根据字典的键值排序,再输出
class Solution:
    def frequencySort(self, s: str) -> str:
        dict = {}
        for i in s:
            if i in dict:
                dict[i] += 1
            else:
                dict[i] = 1
        dict1 = sorted(dict.items(), key=lambda d:d[1], reverse=True)
        print(dict1)
        ans = ''
        for i in dict1:
            ans += i[0] * i[1]
        return ans

4.三数之和

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
—————————————————————————————————————————

简单的方法很好想,时间复杂度却降不下来,最后考虑双指针法,遍历一次数组,再双指针找寻剩下两个数,还需要注意是否会有重复的情况,所以不以重复数做开头
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        res =[]
        i = 0
        for i in range(len(nums)):
            if i == 0 or nums[i]>nums[i-1]:
                l = i+1
                r = len(nums)-1
                while l < r:
                    s = nums[i] + nums[l] +nums[r]
                    if s ==0:
                        res.append([nums[i],nums[l],nums[r]])
                        l +=1
                        r -=1
                        while l < r and nums[l] == nums[l-1]:
                            l += 1
                        while r > l and nums[r] == nums[r+1]:
                            r -= 1
                    elif s>0:
                        r -=1
                    else :
                        l +=1
        return res


以上就是今日经验!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值