ARTS Week2
by
Background: ARTS activity
Algorithm
406. Queue Reconstruction by Height
Input: [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
Output: [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
Intuition solution:
The second number of the tuple represents the # of people in front of the current person. [5, 0] is the first person because he is the one with smallest height among those there is no one taller than him. Next is [7, 0] since [5, 0] is not taller than him. This gives me the key to tackle this problem: iterate the input, find the right person and put him into the queue. In each iteration, find the one with smallest height among those with correct number of taller people in front.
Since the height is the key, then arrange the people according to their height.
Height | Person |
---|---|
4 | [4, 4] |
5 | [5, 0] |
6 | [6, 1] |
7 | [7, 0], [7, 1] |
Pick [5, 0] and put it into the queue. Then there is one more person in front of [4, 4]. Therefore, the number of taller persons in the queue is needed to be remember for each height category and being updated in each iteration.
However, this solution uses O(N^2) time complexity due to the update of the counts. There are some observations from the example input:
- the relative position for people with the same height is not affected by other people in the queue, only affected by the second value of the tuple.
- The position of taller person is not affected by those who are shorter.
Therefore, we can reconstruct the queue by placing the people in the same height category each time in height descending order. In each iteration, insert the tuple into position denoted by the second value since the iteration takes place by height descending order so that there is no one shorter than the current height. By doing this, the second value of the tuple can be regared as the real position in the queue. And this improved solution can downscale the time complexity to O(NlogN) according to the primitive array implementation of the programming language.
Review
Advanced Encoding and Decoding Techniques in Go
This excellent post explains the advanced encoding and decoding technique provided by package “encoding/json”. The package enables customizing the encoding and decoding of data. This leverages the principle of Golang - Implement an interface other than inherit from a base class. This technique serves for several purposes:
- smooth minor differences among data schemas with clean code.
- provide an elegant way to pack and unpack data with different fields.
3 techniques used from the post are concluded as the following:
-
Customize the encoding and decoding on a single field to fix data structures discrepancy.
-
Use double unmarshal to decode a list of similar objects.
-
Improved version of double unmarshal
Tips
Unbuffered channel vs buffered channel in Golang:
In the post Visualizing Concurrency in Go, there is a pattern called Ping-pong. Here we have a channel as a table of the ping-pong game. The ball is an integer variable, and two goroutines-players that ‘hit’ the ball, increasing its value (hits counter):
However, if the channel is not received by the main routine explicitly and one of the player routine is abnomally terminated, the other player rountine gets blocked when sending out the signal through the unbuffered channel. At this point, all the routines are not running, the program becomes deadlock. This is because the channel is unbuffered, all the operations are blocked until the channel is received by some routines. The above example uses a timer and receives from the channel after the timer. However, in some cases we want the routines to finish as fast as possible so that timer is not an approriate tecnique. We may want to merge the result from all routines. In this case, a buffered channel is a more appropriate choice over unbuffered channel. Since the sender sends to the channel with a buffer and the receiver receives from the buffer, the sender is not blocked so that deadlock is prevented.
Sharing
Chaos engineering: Bloom filter on web cache
tags: