leetcode 第169场周赛

5295. 和为零的N个唯一整数

给你一个整数 n,请你返回 任意 一个由 n 个 各不相同 的整数组成的数组,并且这 n 个数相加和为 0 。

想法很简单,就是构造 正负对应的数字,如果奇数就加一个0进去

class Solution(object):
   def sumZero(self, n):
       """
       :type n: int
       :rtype: List[int]
       """
       ans = []
       tmp = n//2
       for i in range(-1*tmp,0):
           ans.append(i)
       if n & 1:
           ans.append(0)
       for i in range(1,tmp+1):
           ans.append(i)
       return ans

给你 root1 和 root2 这两棵二叉搜索树。

5296. 两棵二叉搜索树中的所有元素

请你返回一个列表,其中包含 两棵树 中的所有整数并按 升序 排序

很裸的思路,中序加归并,但是不想那么麻烦,直接遍历+合并排序

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

class Solution(object):
    def getAllElements(self, root1, root2):
        """
        :type root1: TreeNode
        :type root2: TreeNode
        :rtype: List[int]
        """
        ans = self.dfs(root1)
        ans.extend(self.dfs(root2))
        ans.sort()
        return ans
    
    def dfs(self,root):
        if root:
            tmp = []
            tmp.extend(self.dfs(root.left))
            tmp.append(root.val)
            tmp.extend(self.dfs(root.right))
            return tmp
        else:
            return []
        

5297. 跳跃游戏 III

这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i]。

请你判断自己是否能够跳到对应元素值为 0 的 任意 下标处。

注意,不管是什么情况下,你都无法跳到数组之外。

搜索,每一个位置的情况只能往前或者往后跳,所以情况比较少,到达过的点,就标记了不能再次到达。

class Solution(object):
   def canReach(self, arr, start):
       """
       :type arr: List[int]
       :type start: int
       :rtype: bool
       """
       l = 0
       r=len(arr)-1
       vis = [ False for i in arr]
       def dfs(x):
           if xr or vis[x]:
               return False
           tmp = arr[x]
           if tmp==0:
               return True
           vis[x] = True
           ans = dfs(x-tmp) or dfs(x+tmp)
           return ans
       return dfs(start)

5298. 口算难题

给你一个方程,左边用 words 表示,右边用 result 表示。

你需要根据以下规则检查方程是否可解:

每个字符都会被解码成一位数字(0 - 9)。
每对不同的字符必须映射到不同的数字。
每个 words[i] 和 result 都会被解码成一个没有前导零的数字。
左侧数字之和(words)等于右侧数字(result)。
如果方程可解,返回 True,否则返回 False。

其实这个地方完全就是考验编程思维,和dfs剪枝

  • 可以统计每个字符对应的系数,通过系数*对应值获取
  • result 的系数统计为负,那么计算时只需求sum的和,和word 统一处理
  • 前导0的时候统一处理
  • 搜索的时候 如果发现 sum + 最大值*正系数 < 0 或者 sum + 最大值*负系数 > 0,就不再往下搜索
class Solution(object):
    def isSolvable(self, words, result):
        """
        :type words: List[str]
        :type result: str
        :rtype: bool
        """
        notzero = set()
        charset = set()
        mp = {}
        def handle(word,mk):
            tmp = 1
            for i in reversed(word):
                charset.add(i)
                mp[i] = mp.get(i,0)+tmp*mk
                tmp *= 10
            if len(word)>0:
                notzero.add(word[0])
        for word in words:
            handle(word,1)
        handle(result,-1)
        charlist = mp.keys()
        used = [0]*10 # 0-9标记
        positive  = [0]*20
        negative = [0]*20
        for i in range(len(charlist)-1,-1,-1):
            if mp[charlist[i]] > 0 :
                positive[i] += mp[charlist[i]]
            else:
                negative[i] += mp[charlist[i]]
            positive[i] += positive[i+1]
            negative[i] += negative[i+1]
        def dfs(pos,sum):
            if pos == len(charlist):
                return sum==0
            for i in range(9,0,-1):
                if not used[i]:
                    if (positive[pos]*i + sum) <0 or \
                        (negative[pos]*i + sum) >0:
                        return False
                    else:
                        break
            end = 1 if charlist[pos] in notzero else 0
            for i in range(9,end-1,-1):
                if not used[i]:
                    used[i] = 1
                    if dfs(pos+1,mp[charlist[pos]]*i+sum):
                        return True
                    used[i] = 0
            return False
        return dfs(0,0)

你可能感兴趣的:(leetcode 第169场周赛)