Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jianminchen/49430c0a45a3fc53a267cddf61267226 to your computer and use it in GitHub Desktop.
Save jianminchen/49430c0a45a3fc53a267cddf61267226 to your computer and use it in GitHub Desktop.
Hackerrank - kinder garten adventure - segment tree implementation
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution
{
static void Main(String[] args)
{
// SegmentTreeProcessing();
TestSampleTestcase();
}
/*
* Sample test case:
* n = 1
* 1, 0, 0
*
* segment tree:
*
* 0
* / \
* 0 2
* / \ /
* 2 1 1
*
*/
private static void TestSampleTestcase()
{
int n = 3;
int[] extraMinutes = new int[] {1, 0, 0 };
var tree = BuildTree(n, extraMinutes);
Console.WriteLine(FindMaxValue(tree, extraMinutes));
}
/*
* Code change:
*
*/
public static void SegmentTreeProcessing()
{
int n = int.Parse(Console.ReadLine());
var extraMinutes = Console.ReadLine().Split().Select(int.Parse).ToArray();
var tree = BuildTree(n, extraMinutes);
Console.WriteLine(FindMaxValue(tree, extraMinutes));
}
/*
*
*/
private static int FindMaxValue(SegmentTree tree, int[] extraMinutes)
{
int bestIndex = 1;
int best = 0;
for (int i = 1; i <= extraMinutes.Length; i++)
{
var curr = tree.Query(i - 1);
if (curr > best)
{
best = curr;
bestIndex = i;
}
}
return bestIndex;
}
/* Extract a standalone function
*
*/
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;
}
public class SegmentTree
{
private readonly int[] tree;
public SegmentTree(int size)
{
tree = new int[size * 2];
}
/*
* code review: Dec. 10, 2016
* from leaf node,
* left % 2 == 1 => ?
*
*/
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;
}
}
/*
* code review: Dec. 10, 2016
* Find the leaf node, leftmost one
*
*/
public int Query(int index)
{
int res = 0;
int i = index + tree.Length / 2;
for (; i > 0; i >>= 1)
res += tree[i];
return res;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment