CodingTour
ARTS #160

Algorithm

本周选择的算法题是:Construct Target Array With Multiple Sums

规则

You are given an array target of n integers. From a starting array arr consisting of n 1’s, you may perform the following procedure :

  • let x be the sum of all elements currently in your array.
  • choose index i, such that 0 <= i < n and set the value of arr at index i to x.
  • You may repeat this procedure as many times as needed.

Return true if it is possible to construct the target array from arr, otherwise, return false.

Example 1:

Input: target = [9,3,5]
Output: true
Explanation: Start with arr = [1, 1, 1] 
[1, 1, 1], sum = 3 choose index 1
[1, 3, 1], sum = 5 choose index 2
[1, 3, 5], sum = 9 choose index 0
[9, 3, 5] Done

Example 2:

Input: target = [1,1,1,2]
Output: false
Explanation: Impossible to create target array from [1,1,1,1].

Example 3:

Input: target = [8,5]
Output: true

Constraints:

  • n == target.length
  • 1 <= n <= 5 * 104
  • 1 <= target[i] <= 109

Solution

impl Solution {
    
    // TLE
    // pub fn is_possible(target: Vec<i32>) -> bool {
    //     let mut stack = vec![vec![1; target.len()]];

    //     while let Some(arr) = stack.pop() {
    //         if target == arr { return true; }
            
    //         let sum: i32 = arr.iter().sum();
    //         for i in 0..target.len() {
    //             if sum <=target[i] {
    //                 let mut new_arr = arr.clone();
    //                 new_arr[i] = sum;
    //                 stack.push(new_arr)
    //             }
    //         }
    //     }
    //     false
    // }

    pub fn is_possible(target: Vec<i32>) -> bool {
        use std::collections::BinaryHeap;
        let mut queue: BinaryHeap<i32> = BinaryHeap::new();
        let mut sum: i32 = target.iter().sum();
        target.iter().for_each(|item| queue.push(*item));

        while let Some(mut num) = queue.pop() {
            if num == 1 { return true; }
            sum -= num;

            if num <= sum || sum < 1 { return false; }

            num %= sum;
            sum += num;

            queue.push(if num > 0 { num } else { sum })
        }
        
        true
    }
}

Review

10 Key Learnings in Rust after 30,000 Lines of Code

社区里曾经有一个探讨,如果 Rust 增加一个功能,可以用一个开关关掉 borrow checker 功能,你觉得如何?虽然不太可能,但大家得到了一个共识:这个功能一定会大受欢迎。

borrow checker 让人很烦,但也可以换一个角度看它,bc 实际上会让我们“被迫”重新设计程序,当我们开始关注每一个对象、变量的对象图、职责和依赖关系时,我们自然就“得到”了 Rust。

Tip

Rust 认为,alias + mutation 是造成不安全的主要原因,于是做出了「共享不可变、可变不共享」设计,使 Rust 在解决内存安全、多线程数据竞争问题上可以使用相同的抽象,这种熟练应用经典设计解决复杂问题的方式,体现了非常强的创新、抽象能力。

Share

什么是教练?

教练是帮助团队达成目标的关键角色。

类比球队里的教练,他们帮助团队实现成功的路上做了哪些事,和球员同吃同睡?改善球员的饮食结构?制定多元化的训练,强化核心力量?…

这些都对,但关键点只有一个:拿掉卡在齿轮里的东西。这是唯一的目标。

对公司的研发团队来说,我们希望团队开发的产品:

  • 线上运行稳定点(减少 P0、提高可用性)
  • 提测质量高一点(代码质量、埋点质量、性能质量)
  • 发版过程顺一点(自动化、流程、工具)

然而团队作为一个实体、一个系统,还没办法做的那么理想化,但正是因为团队存在种种问题,我们这些所谓的 leader、manager 才有价值,我们要跟着大家一起解决遇到的难题、bug,找到阻碍团队质量的齿轮,Lead by Myself,而不只是评估团队表现。

做好团队的质量教练,可以下面这些方法。

了解团队的人和事,找到卡在团队齿轮里的东西是什么,确定团队目标:

  • 团队要关注的重点质量指标是什么,为什么它重要
  • 团队的高质量提测人比例有多少,为什么有些人会更高,如何进一步提高比例(了解动机)
  • 不存在无端消极的团队,找到病根很重要,不能停留表象,要深入其中

跟大家一起去解决问题,拿掉卡在齿轮里的东西:

  • 可能是一个难题、一个 bug、一个人、一件事

持续运转:抓关键目标,让大家一起尝到甜头,让团队动起来。

教练本质工作是帮助人成为明星,他是一位陪伴者,使用提问的方式、分享的方式、建议的方式,帮助实现目标,对教练来说,做一个项目和打一场球赛没什么分别。