Saturday, December 10, 2016

Segment Tree - kindergarten adventures algorithm - code review

Dec. 10, 2016

Problem statement:

Introduction

Kindergarten adventure algorithm is the algorithm on HackerRank university codespring contest in November, 2016, and it is medium level difficulty. Julia spent over one hour to think about the algorithm in the contest, but she did not come out the idea using binary indexed tree or segment tree to solve it. Julia was very lucky to find a C# solution actually implemented using segment tree.

The Previous two blogs about the algorithm and solutions:

HackerRank - university codesprint - kindergarten adventures (after the contest)



Julia found out that her learning of binary indexed tree is missing most important part, the experience to play and learn from a simple concrete example; she read a lot about segment tree, or binary index tree, but she needs to have some time to play with an example, have some fun. The skills will come afterwards, she believes.

Here is one C# solution she chose to study, here are steps:
1. Put some analysis together,
2. Review code
3. Put together a new version
4. Share on stackexchange.com code review section.

C# code

Plan to work on the algorithm 2 hours. Dec. 10, 2016, 11:36am - 1:36pm

Put some references together for further study.

Workout


C# code - Julia tries to figure out how to build a segment tree through sample test
case:
3
1 0 0
The segment tree in an array: {0,0,2,2,1,1}

Segment Tree:

C# code

Julia's concerns about segment tree:

Questions:

1. Why does Modify function skip one and only add value on odd number?

Line 114 - line 125,

        public void Modify(int start, int count, int value)
        {
            int size = tree.Length / 2;
            int left = start + size;
            int right = start + count + size; // open border

            for (; left < right; left >>= 1, right >>= 1)
            {
                if (left  % 2  == 1) tree[left++]   += value;
                if (right % 2 == 1) tree[--right]  += value;
            }
        }

2. How does the range of start/ end to be determined on this simple test case: 1 0 0?

Line 87 - Line 93:
private static SegmentTree BuildTree(int n, int[] extraMinutes)
    {
        var tree = new SegmentTree(n);
        for (int i = 0; i < n; i++)
        {
            int curr = extraMinutes[i];
            int len  = extraMinutes.Length;

            if (curr >= len) continue;

            int start = (i + 1) % len;
            int end   = (i + extraMinutes.Length - curr) % len;

            if (start <= end)
                tree.Modify(start, end - start + 1, 1);
            else
            {
                tree.Modify(start, len - start, 1);
                tree.Modify(0,     end + 1,     1);
            }
        }

        return tree;
    }

Why start = (i+1) % len? Guessing,  i = 0, ID counts from 1 to 3, not starting from 0.
Why end  = (i + extraMinutes.Length - curr) % len;

3. Question:
Study Query API: Why skip the root node?
for loop, i > 0

Line 132 - Line 139:
public int Query(int index)
        {
            int res = 0;
            int i = index + tree.Length / 2;
            for (; i > 0; i >>= 1)
                res += tree[i];
            return res;
        }


Actionable Items


Julia, only way, better way to learn segment tree, binary index tree, is to work on an algorithm, and then, ask good questions to yourself, and then, post the question on the stackexchange.com as well.

Post the question on stackexchange.com code review:

Code review is here. The code review was closed.

It is not acceptable to ask help to understand other people's code. That is the rule from stackexchange.com. Do not be lazy. Work hard, fail a few times and then get better. Julia, if you are in uncomfortable zone, that is the learning zone. Do not miss the learning opportunities.

Fail to post, the algorithm written is not mine. Need to come out my own solution first, and then, get code review. Tried various solutions, failed all times. Get to know the algorithm better.

1. Wrote my own version of segment tree, first try: 2.18 (maximum score 30)
only pass 4 test cases.

C# practice 1

2. Second practice, score 1.08 max-score: 30, pass test case 0 and 1.

C# practice 2

3. Third practice, score 0  max-score: 30, pass test case 0, 1

C# practice 3

It is a really good study case for understanding depth of problem solving. Timeout issue is critical, at the beginning of construction of segment tree, the time complexity should be O(n^2), not O(n), n is the people in the group, n < 100000.

Better score 0 to write your own code, comparing to copy other's code score 30. But do not understand the design and algorithm. 

References


1. Read the lecture note to help:

Lecture note to study.

2. Read the article about segment tree.



No comments:

Post a Comment