Min Loss, by HackerRank

Problem statement is here: https://www.hackerrank.com/challenges/minimum-loss. At first I thought about an N^2 solution, but with N ~= 10^5, such approach would definitely time out. I read some of the discussions (no shame, really, purpose of hacker-rank practice is for one to learn) and an idea was brought up there:

  •  Build a Binary Search Tree out of the numbers
  •  As you add a new number, while going down the tree keep track of the min-loss

Assuming that the tree is going to be relatively balanced (and that's a fair assumption given the statement that the input numbers are all unique), the execution time becomes near NLogN, which works quick enough for N ~= 10^5. Code is below, and a picture of me and the team who's bringing Bots to Search Engines!!! :) Many cheers, Marcelo.



using System;
using System.Collections.Generic;
using System.IO;
class Solution
{
    static void Main(String[] args)
    {
        int n = Int32.Parse(Console.ReadLine());
        long minLoss = Int64.MaxValue;
        string[] parts = Console.ReadLine().Split(' ');

        BST bst = new BST(Int64.Parse(parts[0]));
        for (int i = 1; i < n; i++)
        {
            bst.Add(Int64.Parse(parts[i]), ref minLoss);
        }
        Console.WriteLine(minLoss);
    }
}

class BST
{
    private long number;
    private BST left;
    private BST right;

    private BST() { }

    public BST(long number)
    {
        this.number = number;
        this.left = null;
        this.right = null;
    }

    public void Add(long number,
                    ref long minLoss)
    {
        if (number >= this.number)
        {
            if (this.right == null)
            {
                this.right = new BST(number);
            }
            else
            {
                this.right.Add(number, ref minLoss);
            }
        }
        else
        {
            if (this.number - number < minLoss) minLoss = this.number - number;
            if (this.left == null)
            {
                this.left = new BST(number);
            }
            else
            {
                this.left.Add(number, ref minLoss);
            }
        }
    }
}

Comments

  1. Thanks Marcelo. I am glad that you liked it :)

    ReplyDelete
  2. very nice Marcelo! Since uniqueness is not necessarily enough to guarantee a balanced tree (take 2, 3, ..., 1000, 1 for example) and I'm too lazy to implement a balanced BST, so I just used a Red-Black tree conveniently provided by C++'s standard library. Note, that I have to perform 2 logN operations on every iteration, but it's still a guaranteed O(NlogN) :)

    http://ideone.com/RHYhTP

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    using namespace std;


    int main() {
    int n; cin >> n;
    long min_loss = numeric_limits::max();

    vector prices(n);
    for (int i = 0; i < n; ++i) cin >> prices[i];

    set seen;
    seen.insert(prices.back());
    for (int i = n-2; i >= 0; --i) {
    long buy = prices[i];
    auto sell = seen.lower_bound(buy);
    if (sell != seen.cbegin()) min_loss = min(min_loss, buy - *prev(sell));
    seen.insert(buy);
    }
    cout << min_loss << endl;
    return 0;
    }

    ReplyDelete

Post a Comment

Popular posts from this blog

Advent of Code - Day 6, 2024: BFS and FSM

Golang vs. C#: performance characteristics (simple case study)

Advent of Code - Day 7, 2024: Backtracking and Eval