LeetCode 第 21 场双周赛

1、给你一个字符串 s ,请你根据下面的算法重新构造字符串:
1)从 s 中选出 最小 的字符,将它 接在 结果字符串的后面。
2)从 s 剩余字符中选出 最小 的字符,且该字符比上一个添加的字符大,将它 接在 结果字符串后面。
3)重复步骤 2 ,直到你没法从 s 中选择字符。
4)从 s 中选出 最大 的字符,将它 接在 结果字符串的后面。
5)从 s 剩余字符中选出 最大 的字符,且该字符比上一个添加的字符小,将它 接在 结果字符串后面。
6)重复步骤 5 ,直到你没法从 s 中选择字符。
7)重复步骤 1 到 6 ,直到 s 中所有字符都已经被选过。
在任何一步中,如果最小或者最大字符不止一个 ,你可以选择其中任意一个,并将其添加到结果字符串。请你返回将 s 中字符重新排序后的 结果字符串 。

示例 :
输入:s = “aaaabbbbcccc”
输出:“abccbaabccba”
解释:
第一轮的步骤 1,2,3 后,结果字符串为 result = “abc”
第一轮的步骤 4,5,6 后,结果字符串为 result = “abccba”
第一轮结束,现在 s = “aabbcc” ,我们再次回到步骤 1
第二轮的步骤 1,2,3 后,结果字符串为 result = “abccbaabc”
第二轮的步骤 4,5,6 后,结果字符串为 result = “abccbaabccba”

class Solution:
    def sortString(self, s: str) -> str:
        arr=[]
        for i in range(26):
            arr.append(chr(ord('a')+i))
        for i in range(26):
            arr.append(chr(ord('z')-i))
        ret=""
        while s:
            for i in arr:
                p=s.find(i)
                if p!=-1:
                    ret=ret+i
                    s=s[:p]+s[p+1:]
        return ret


from collections import OrderedDict
class Solution:
    def sortString(self, s: str) -> str:
        ss = sorted(s)
        cnt = OrderedDict()
        for ch in ss:
            if ch not in cnt:
                cnt[ch] = 1
            else:
                cnt[ch] += 1
        res = ""
        while len(res) < len(ss):
            for k, v in cnt.items():
                if v > 0:
                    res += k
                    cnt[k] -= 1

            for k, v in reversed(cnt.items()):
                if v > 0:
                    res += k
                    cnt[k] -= 1
        return res

2、给你一个字符串 s ,请你返回满足以下条件的最长子字符串的长度:每个元音字母,即 ‘a’,‘e’,‘i’,‘o’,‘u’ ,在子字符串中都恰好出现了偶数次。

示例 1:
输入:s = “eleetminicoworoep”
输出:13
解释:最长子字符串是 “leetminicowor” ,它包含 e,i,o 各 2 个,以及 0 个 a,u 。

示例 2:
输入:s = “leetcodeisgreat”
输出:5
解释:最长子字符串是 “leetc” ,其中包含 2 个 e 。

这里涉及一个异或解决办法,n XOR (1<

异或问题:n xor 0 = n, n xor n = 0,可以用于奇偶校验,运算消耗很小

class Solution:
    def findTheLongestSubstring(self, s: str) -> int:
        lookup = {0:-1}
        vowels = {'a':0,'e':1,'i':2,'o':3,'u':4}
        
		# buf用五位二进制表示五个字母的奇偶状态
        i,buf = 0,0
        res = 0
        while i < len(s):
            if s[i] in vowels:
                buf ^= (1 << vowels[s[i]])
            if buf in lookup:
                res = max(res,i - lookup[buf])
            else: lookup[buf] = i
            i += 1
        return res

class Solution:
    def findTheLongestSubstring(self, s: str) -> int:
        index = {(0, 0, 0, 0, 0): -1}
        cnt = {'a': 0, 'e': 0, 'i': 0, 'o': 0, 'u': 0}
        ans = 0
        for i, c in enumerate(s):
            if c in 'aeiou':
                cnt[c] += 1
                cnt[c] %= 2
            key = tuple(cnt.values())
            if key not in index:
                index[key] = i
            else:
                ans = max(ans, i - index[key])
        return ans

3、给你一棵以 root 为根的二叉树,二叉树中的交错路径定义如下:
1)选择二叉树中 任意 节点和一个方向(左或者右)。
2)如果前进方向为右,那么移动到当前节点的的右子节点,否则移动到它的左子节点。
3)改变前进方向:左变右或者右变左。
4)重复第二步和第三步,直到你在树中无法继续移动。
交错路径的长度定义为:访问过的节点数目 - 1(单个节点的路径长度为 0 )。请你返回给定树中最长交错路径 的长度。
LeetCode 第 21 场双周赛_第1张图片输入:root = [1,null,1,1,1,null,null,1,1,null,1,null,null,null,1,null,1]
输出:3

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def longestZigZag(self, root: TreeNode) -> int:
        self.ans = 0
        def dfs(root):
            if not root:
	            return 0, 0
            ll, lr = dfs(root.left)
            rl, rr = dfs(root.right)
            l = lr + 1
            r = rl + 1
            self.ans = max(self.ans, l, r)
            return l, r

        if not root:
            return 0
        dfs(root)
        return self.ans - 1

class Solution:
    def longestZigZag(self, root: TreeNode) -> int:
        self.res = 0
        
        def f(r, pre, length):
            if r:
                self.res = max(self.res, length)
                if r.left and pre == "left":
                    f(r.left, "left", 1)
                elif r.left and pre == "right":
                    f(r.left, "left", length + 1)
                if r.right and pre == "right":
                    f(r.right, "right", 1)
                elif r.right and pre == "left":
                    f(r.right, "right", length + 1)

        f(root.right, "right", 1)
        f(root.left,"left", 1)
        return self.res

4、给你一棵以 root 为根的 二叉树 ,请你返回 任意 二叉搜索子树的最大键值和。二叉搜索树的定义如下:
1)任意节点的左子树中的键值小于此节点的键值。
2)任意节点的右子树中的键值大于此节点的键值。
3)任意节点的左子树和右子树是二叉搜索树。
LeetCode 第 21 场双周赛_第2张图片
输入:root = [1,4,3,2,4,2,5,null,null,null,null,null,null,4,6]
输出:20
解释:键值为 3 的子树是和最大的二叉搜索树。
提示:每棵树最多有 40000 个节点。每个节点的键值在 [-4 * 10^4 , 4 * 10^4] 之间。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

inf = int(1e9)
class Solution:     
    def maxSumBST(self, root: TreeNode) -> int:
        def dfs(root):
            if not root:
                return True, 0, inf, -inf

            l, lsum, lmin, lmax = dfs(root.left)
            r, rsum, rmin, rmax = dfs(root.right)
            
            if l and r and lmax < root.val < rmin:
                s = lsum + rsum + root.val
                self.ans = max(s, self.ans)
                mini = min(lmin, root.val)
                maxi = max(rmax, root.val)
                return True, s, mini, maxi
            return False, 0, 0, 0

        self.ans = 0
        dfs(root)
        return self.ans

你可能感兴趣的:(leetcode)