CodingTour
ARTS #93

Algorithm

本周选择的算法题是:Symmetric Tree

规则

Given the root of a binary tree, check whether it is a mirror of itself (i.e., symmetric around its center).

Example 1:

img

Input: root = [1,2,2,3,4,4,3]
Output: true

Example 2:

img

Input: root = [1,2,2,null,3,null,3]
Output: false

Constraints:

  • The number of nodes in the tree is in the range [1, 1000].
  • -100 <= Node.val <= 100

Solution

递归解法:

class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:

        def is_mirror(tree1, tree2) -> bool:
            if tree1 is None and tree2 is None: return True
            if tree1 is None or tree2 is None: return False
            return tree1.val == tree2.val and is_mirror(tree1.left, tree2.right) and is_mirror(tree1.right, tree2.left)
        
        return is_mirror(root, root)

迭代解法:

class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:
        stack = [root, root]
        while stack:
            tree1, tree2 = stack.pop(0), stack.pop(0)
            if tree1 is None and tree2 is None: continue
            if tree1 is None or tree2 is None: return False
            if tree1.val != tree2.val: return False

            stack.append(tree1.left)
            stack.append(tree2.right)
            stack.append(tree1.right)
            stack.append(tree2.left)
        return True

两种解法都利用了层序遍历的思想。

Review

随着 Flutter 2.0 的发布,Flutter 完成了对全平台的支持:

  • 移动平台 - iOS/Android
  • 桌面平台 - Win/macOS/Linux
  • Web 平台

我很好奇 Flutter 打算如何帮助开发者开发出全平台兼容的应用 - 而不是一个平台一个应用。

为此我查阅了 Flutter API、社区文章以及 Flutter 官方提到的 Flutter Folio 的源码,我得到的最终结论如下:

  • Flutter 为各个平台提供了丰富的 API
  • 最困难的工作仍然需要开发者自己完成:适应平台间的差异

比如 Flutter Folio 应用的首页,它需要这样去兼容不同尺寸的设备:

image-20210313163747876

虽然没有银弹可以用,但幸好我们还是有一些普适的方法可以参考:

  1. 预见适应性 - 项目立项之初或许只支持一个平台,不过这是一个绝好的机会去考虑适应性,提前做一些主题、配置相关的 Widgets,这件事做的越早越简单
  2. 避免硬编码 - 尽量将各种间距之类的数字写到配置文件里,减少 magic number
  3. 尽可能将你的 Widgets 拆分的更小 - 我们要认识到,有些 Widgets 是用来提供展示的,有些 Widgets 是用来缝合的,后者相当于是平台胶水层,参考 Flutter Folio 的 home_page.dart,更小的 Widgets 更有利于重用
  4. 借助一些工具测试你的应用的适应性,如 Device Preview

这只是冰山一角,关于 Flutter 提供的各种平台 API 的用法,可以参考文章: Designing truly adaptative user interfaces

Tip

随着内部服务越来越多,原本的 NGINX 配置方式维护成本太高了,原先的方式是:

  • 针对不同的 server 写不同的 conf
  • 将这些 conf 软链接到 /usr/local/etc/nginx/servers 下
  • 在 nginx.conf 里 include servers

最主要的问题是代码没有和配置分离,没有意识到它们的更新逻辑不一样。

更好的方式是将各个 server 的 conf 放到一个仓库里,然后直接设置这个仓库的软链接地址即可。

隐私信息不要放仓库里,例如 SSL 证书。

Share

Bignum in Python: 内存中的存储