Algorithm
本周选择的算法题是:Subarray Sums Divisible by K。
规则
Given an integer array nums
and an integer k
, return the number of non-empty subarrays that have a sum divisible by k
.
A subarray is a contiguous part of an array.
Example 1:
Input: nums = [4,5,0,-2,-3,1], k = 5
Output: 7
Explanation: There are 7 subarrays with a sum divisible by k = 5:
[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]
Example 2:
Input: nums = [5], k = 9
Output: 0
Constraints:
1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
2 <= k <= 104
Solution
impl Solution {
pub fn subarrays_div_by_k(nums: Vec<i32>, k: i32) -> i32 {
let mut ans = 0;
let mut modGroups = vec![0; k as usize];
modGroups[0] = 1;
let mut prefixMod = 0;
for num in nums {
prefixMod = (prefixMod + num % k + k) % k;
ans += modGroups[prefixMod as usize];
modGroups[prefixMod as usize] += 1;
}
ans
}
}
Review
Here are my “lessons learned” after 5+ years of DevOps consulting
作者在这篇文章里分享了诸多经验,标题中的关键词有两个:DevOps、consulting,本文着重介绍的是交付、客户和沟通、协作。
介绍其中三个 tips:
- 文档写作要尽可能早和快。早是为了减少风险,快是为了真的完成它。作者的工作是顾问,顾问难以避免与人打交道,而文档是连接 people 和 processes 的工具之一,想让文档发挥作用,最基本的是不要试图同时写和编辑,大概率会陷入完美主义的陷阱中。有意思的是,很多知名作家在采访时也表达过类似的观点,通常手稿和前几版要一气呵成,尽量避免边写作边修改,因为那样可能永远也完不成一件作品
- 尽早通过基础设施即代码和发布流水线完成一次 release。“大爆炸” 理论也适用于软件交付。一次巨大的爆炸可能产生新的宇宙,生产部署也可能是这样的,每次基础设施和代码的大规模部署,要么是混乱的结果,要么(运气好)是一个可工作的应用程序,如今很多公司仍旧是在项目 “完成” 的最后一天才发布到生产,这种行为像极了在最后一刻期望通过 hope and pray 获得 “大爆炸” 的眷顾
- 让和客户参与设计,共同创作。You can’t hide。顾问面向的是 B 端客户,因此需要一些必要的软技能完成 “最难的事” — 和客户一起工作、帮助客户拿到结果、赢得客户的信任。Re-adjust your pace to match the client’s pace,可以翻译为 “与客户同频”,没有所谓的快与慢、好与差,这些都是相对的,能站在客户角度讲清楚风险和收益比 “最佳实践” 更重要
作者文笔不错,总而言之是很不错的文章。
Tip
用于测试 Apple Push 的小工具:Knuff,Apple 证书设置起来比较麻烦,加上国内往往会借助三方平台(如极光)作为推送中间件,过程中遇到问题不好排查是证书导致的还是配置不正确,此时用 Knuff 可以方便排查。
Share
分享几个 Python f-strings 的妙用~
f-strings 一般被用来格式化字符串,比如原本的:
name = "Musk"
age = 52
print("Hello, %s. You are %s." % (name, age))
# Hello Musk. You are 52.
用 f-strings 只需要:
name = "Musk"
age = 52
print(f"Hello, {name}. You are {age}.")
# Hello Musk. You are 52.
是一个让工作和生活变得更轻松的好工具,不过 f-strings 的功能远不只如此。
日期和时间格式化
日期转为字符串不用显式通过 strftime
完成:
import datetime
today = datetime.datetime.today()
print(f"{today:%Y-%m-%d}")
# 2023-01-17
print(f"{today:%Y}")
# 2023
具体语法参见: strftime - format date and time。
变量名和调试
x = 10
print(f"x = {x}")
print(f"{x = :}") # 两者等价
print(f"{x = :.3f}") # 可以添加修饰符
字符串表示
打印一个类时,默认是调用 __str__
方法,如果想调用 __repr__
只需要加上 !r
就好:
class User:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def __str__(self):
return f"{self.first_name} {self.last_name}"
def __repr__(self):
return f"User's name is: {self.first_name} {self.last_name}"
user = User("Elon", "Musk")
print(f"{user}")
# Elon Musk
print(f"{user!r}")
# User's name is: Elon Musk
完全支持格式化规范
f-strings 支持 Format Specification Mini-Language,所以你可以用很多修饰符:
text = "hello world"
# Center text:
print(f"{text:^15}")
# ' hello world '
number = 1234567890
# Set separator
print(f"{number:,}")
# 1,234,567,890
number = 123
# Add leading zeros
print(f"{number:08}")
# 00000123
除了格式化数字、日期外,对齐、居中、添加前导零、空格等等,其他格式化方案支持的 f-strings 同样也支持。
可嵌套
number = 254.3463
print(f"{f'${number:.3f}':>10s}")
# ' $254.346'
变量也支持:
import decimal
width = 8
precision = 3
value = decimal.Decimal("42.12345")
print(f"output: {value:{width}.{precision}}")
# 'output: 42.1'
条件格式化
f-strings 支持三元运算符:
x = 10
print(f"{x if x > 5 else '1'}")
# 10
Lambda
print(f"{(lambda x: x**2)(3)}")
# 9
结束语
正如你看到的,f-strings 具有比大多数人想象不到的更多功能,其实这些功能在 Python 的文档里都有提及,参见: PEP 498 – Literal String Interpolation,因此我们不仅要阅读 f-strings,也建议阅读可能使用的任何其他 Python 模块/特性的文档,深入研究文档通常会发现一些即使在 StackOverflow 中也找不到的非常有用的功能,而且 f-strings 实际上是 Python 所有格式化方案中最快的,即时你喜欢用老派的方法,也可以考虑为了提高性能切换到 f-strings。
ps: 不建议在 f-strings 中使用太多 lambda、条件格式化和嵌套,虽然它支持,但无疑会降低代码的可读性。