ARTS 第 39 周

每周完成一个 ARTS:
Algorithm: 每周至少做一个 LeetCode 的算法题
Review: 阅读并点评至少一篇英文技术文章
Tips: 学习至少一个技术技巧
Share: 分享一篇有观点和思考的技术文章


Contents


Algorithm

172. Factorial Trailing Zeroes

题目:172. Factorial Trailing Zeroes

难度:Easy

题意:Given an integer n, return the number of trailing zeroes in n!.

示例 1:

Input: 3
Output: 0
Explanation: 3! = 6, no trailing zero.

示例 2:

Input: 5
Output: 1
Explanation: 5! = 120, one trailing zero.

说明:Your solution should be in logarithmic time complexity.

解法:这道题乍一看我们很容易会想:不就是计算阶乘结果尾数中 0 的个数吗,直接计算之后再去数不就行了?但只要你稍微仔细想一想就会发现,阶乘尾数中 0 的个数,其实就是阶乘展开之后 10 的个数。再仔细想,数 10 的个数其实就是数 5 的个数,因为 2 * 5 = 10,而 5 往下的阶乘中一定含有 2,那么只要统计阶乘中出现了几个 5 就可以统计出结果尾数中出现了几个 0。实际上,n 的阶乘中 5 的个数就是 n 除以 5 的结果中的整数部分,这一点很容易想到,只要想到了这一点,代码就非常容易写了。

代码:

class Solution:
    def trailingZeroes(self, n: int) -> int:
        result = 0

        while n != 0:
            result += n // 5
            n = n // 5

        return result

题目中要求的 O(log N) 的时间复杂度在这里也很好地满足了,因为这里的时间复杂度其实是以 5 为底的对数,用大 O 表示即是 O(log N)。


Review

Lessons From Ancient Philosophers That Can be Applied to Everyday Life

本周开始,我和「奔跑吧攻城狮」号主 Dimple 合作,出一个英文技术文章学习的专栏,每周针对一篇英文技术文章进行精读和讨论,旨在提升我们对英文文章的阅读理解能力。感兴趣的朋友可以关注一下公众号【奔跑吧攻城狮】,还可以加小编微信,进群进一步讨论交流哦!

本周选文为 Medium 上的一篇高赞文章《Lessons From Ancient Philosophers That Can be Applied to Everyday Life》。文章不算长,但有不少高级词汇和名人名言。

本文通过引用几位古典哲学家的思想和名言,讲述了当今生活中可以常用的几个原则,帮助我们成为更明智、更少焦虑、更深思熟虑、更好的人:

zsxq


Tips

在 R 中查看函数的源码

一个特别小的技巧:在 R console 中,你可以运行函数的名称而不加上括号 (),来查看这个函数的源码。例如我们想要查看拟合线性模型函数 lm() 的源码,只需要在 R console 中执行:

> lm

R console 就会给你返回:

> lm
function (formula, data, subset, weights, na.action, method = "qr",
    model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE,
    contrasts = NULL, offset, ...)
{
    ret.x <- x
    ret.y <- y
    cl <- match.call()
    mf <- match.call(expand.dots = FALSE)
    m <- match(c("formula", "data", "subset", "weights", "na.action",
        "offset"), names(mf), 0L)
    mf <- mf[c(1L, m)]
    mf$drop.unused.levels <- TRUE
    mf[[1L]] <- quote(stats::model.frame)
    mf <- eval(mf, parent.frame())
    if (method == "model.frame")
        return(mf)
    else if (method != "qr")
        warning(gettextf("method = '%s' is not supported. Using 'qr'",
            method), domain = NA)
    mt <- attr(mf, "terms")
    y <- model.response(mf, "numeric")
    w <- as.vector(model.weights(mf))
    if (!is.null(w) && !is.numeric(w))
        stop("'weights' must be a numeric vector")
    offset <- as.vector(model.offset(mf))
    if (!is.null(offset)) {
        if (length(offset) != NROW(y))
            stop(gettextf("number of offsets is %d, should equal %d (number of observations)",
                length(offset), NROW(y)), domain = NA)
    }
    if (is.empty.model(mt)) {
        x <- NULL
        z <- list(coefficients = if (is.matrix(y)) matrix(NA_real_,
            0, ncol(y)) else numeric(), residuals = y, fitted.values = 0 *
            y, weights = w, rank = 0L, df.residual = if (!is.null(w)) sum(w !=
            0) else if (is.matrix(y)) nrow(y) else length(y))
        if (!is.null(offset)) {
            z$fitted.values <- offset
            z$residuals <- y - offset
        }
    }
    else {
        x <- model.matrix(mt, mf, contrasts)
        z <- if (is.null(w))
            lm.fit(x, y, offset = offset, singular.ok = singular.ok,
                ...)
        else lm.wfit(x, y, w, offset = offset, singular.ok = singular.ok,
            ...)
    }
    class(z) <- c(if (is.matrix(y)) "mlm", "lm")
    z$na.action <- attr(mf, "na.action")
    z$offset <- offset
    z$contrasts <- attr(x, "contrasts")
    z$xlevels <- .getXlevels(mt, mf)
    z$call <- cl
    z$terms <- mt
    if (model)
        z$model <- mf
    if (ret.x)
        z$x <- x
    if (ret.y)
        z$y <- y
    if (!qr)
        z$qr <- NULL
    z
}
<bytecode: 0x7fef1779aec0>
<environment: namespace:stats>

Share

VS Code 中的代码折叠和面包屑(Breadcrumbs)功能

这周我们来看一下 VS Code 中关于代码折叠和面包屑的功能。

代码折叠

首先是「代码折叠」。

举一个简单的例子,我们有下面一段 JS 代码:

function hw() {
    console("Hello world!");
}

当我们把鼠标指针移动到行号附近,我们可以看到一个向下的箭头(或者是一个减号标记,取决于你安装的主题,但形式差不多),点击这个箭头,你会发现 hw() 这个函数中间的内容消失了,被三个点代替。

代码折叠功能同样支持其他语言如 Python:

code folding

代码折叠的一些快捷键如下:

更详细折叠方案的可以参考官方文档

面包屑(Breadcrumbs)

VS Code 中提供了快四跳转到某个函数或章节的面包屑功能,举个我现在正在写的这篇文章的例子:

Breadcrumbs

在标签页的正下方你可以看到有一排类似于导航栏的东西,你可以点击每个文字,在不同的文件夹、文件、模块或是函数之间进行跳转,这个工具栏和我们在 VS Code 左侧的资源管理器中看到的层级结构是一致的,但是更方便在编写代码的时候直接进行跳转。