Algorithm

题目一

题目描述

使用栈实现队列的操作:push(), peek(), pop(), empty()操作,只能使用标准的栈操作 – 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。232 用栈实现队列

题目解答

由于队列是FIFO,而栈是FILO,要想使用栈来实现队列,则可以使用两个栈来达到目的,即负负到正,核心点就是pop()和peek()方法的处理上,在调用pop()与peek()方法时都在要从outStack中来操作,如果outStack不为空,则直接进行操作,否则要把inStack中的元素添加到outStack中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import java.util.Iterator;
import java.util.Stack;

class MyQueue {

    private Stack<Integer> inputStack;
    private Stack<Integer> outStack;

    /** Initialize your data structure here. */
    public MyQueue() {
        inputStack = new Stack<>();
        outStack = new Stack<>();
    }

    /** Push element x to the back of queue. */
    public void push(int x) {
        inputStack.push(x);
    }

    /** Removes the element from in front of queue and returns that element. */
    public int pop() {

        if (empty()) {
            return -1;
        }

        if (outStack.empty()) {
            while (!inputStack.empty()) {
                outStack.push(inputStack.pop());
            }
        }
        return outStack.pop();
    }

    /** Get the front element. */
    public int peek() {

        if (empty()) {
            return -1;
        }

        if (outStack.empty()) {
            while (!inputStack.empty()) {
                outStack.push(inputStack.pop());
            }
        }
        return outStack.peek();
    }

    /** Returns whether the queue is empty. */
    public boolean empty() {

        return inputStack.empty() && outStack.empty();
    }
}

时间复杂度:push O(1), pop O(n), peek O(n)

题目二

题目描述

使用队列实现栈的push(), pop(), top(), empty()操作,只能使用队列的基本操作– 也就是 push to back, peek/pop from front, size, 和 is empty。225 用队列实现栈

题目解答

与上题相反,要用队列实现栈,也是使用了两个队列的方法,在操作中保存住栈的头元素,当要进行pop时,则要把inQueue中的n-1个元素push到outQueue中,再将inQueue与outQueue进行交换,最后pop出的都是outQueue(因为outQueue中只剩下最后一个元素了,outQueue就是先前的inQueue)中的元素

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import java.util.LinkedList;
import java.util.Queue;

//leetcode submit region begin(Prohibit modification and deletion)
class MyStack {

    private Queue<Integer> inQueue;
    private Queue<Integer> outQueue;
    private int top;

    /** Initialize your data structure here. */
    public MyStack() {
        inQueue = new LinkedList<>();
        outQueue = new LinkedList<>();
    }

    /** Push element x onto stack. */
    public void push(int x) {
        top = x;
        if (inQueue.isEmpty()) {
            outQueue.add(x);
        } else {
            inQueue.add(x);
        }
    }

    /** Removes the element on top of the stack and returns that element. */
    public int pop() {

        if (empty()) {
            return -1;
        }
        if (inQueue.isEmpty()) {
            while (outQueue.size() > 1) {
                top = outQueue.poll();
                inQueue.offer(top);
            }
            return outQueue.poll();

        } else {
            while (inQueue.size() > 1) {
                top = inQueue.poll();
                outQueue.offer(top);
            }
            return inQueue.poll();
        }

    }

    /** Get the top element. */
    public int top() {

        if (empty()) {
            return -1;
        }

        return top;
    }

    /** Returns whether the stack is empty. */
    public boolean empty() {
        return inQueue.isEmpty() && outQueue.isEmpty();
    }
}

时间复杂度:push O(1), pop O(n), top O(1)

Review

LinkedIn的代码Review讲述LinkedIn公司如何进行高效代码审查的。LinedIn的内部审查的方式:

  1. 代码审查是强制的,生产上线前的代码都要经过团队成员进行审查,公司使用统一的代码审查工具,这给跨团队审查带来便利
  2. 代码审查帮公司形成了一种健康的反馈文化,员工把代码审查作为专业成长的机会

代码审查的最佳实践

代码提交要有详细的说明

每个代码提交都要有关于修改或者设计的说明(动机),这样有利于审查者快速了解提交的目的,还提高了提交代码的文档质量。

代码审查者要给出积极的反馈

代码审查者不仅要关注代码中的问题,对于实现的好的代码也要给于充分的肯定与表扬,并要给出具体的说明。这样形成了正向反馈。

代码审查者的反馈要做到简单清晰

代码审查者要对有问题的代码标识清晰的反馈说明,做有目的性的说明,这样可以明确团队的价值观。

肯定每一位提交者的劳动

对于一些不好的代码提交,审查者也要对提交者的努力给予肯定。努力工作是要得到肯定的,因为这样会让人有价值感。

正视审查反馈

对于审查反馈提交人员也要确定哪些是有用,哪些是无用的,如果无用,那就把注释删除掉。

提交的代码要明确说明测试情况

在写提交说明时,测试的情况说明是强制的,对于软件开发来说,测试输出的同步非常重要。

代码样式与格式应该由自动化工具完成

审查只针对代码实现,对于样式与格式应在早期规定好,不要在这上面浪费时间。

代码审查是工作的一部分

享受它,重视它,对于提高自我与团队意义非凡。

Tip

在命令行中一般都使用zsh做为默认shell,它提供了一种History操作的好的体验方式,即可以输入命令前缀,使用up-line-or-search或者down-line-or-search来进行针对该命令的历史补全,例如输入mvn 后,使用此命令可以补全输入历史指定mvn开头的命令了。以下配置将命令分别绑定在arrow up与arrow down键下

1
2
bindkey '^[[A' up-line-or-search
bindkey '^[[B' down-line-or-search

Share

Simple Systems Have Less Downtime简单的系统拥有更少的停机时间。作者以一个前造船工程师和现在创业公司的营销顾问来说明简单系统的重要性,作者把软件开发与世界上最大的集装箱船运行来进行说明简单系统的好处,并解释说明了为什么简单系统会减少停机时间。因为简单的系统可以熟练使用,便于故障的排除,还有更多的替代方案。作者还用一个真实的创业故事来进行阐述说明。