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:
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);
}
}
}
}
- 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);
}
}
}
}
Thanks Marcelo. I am glad that you liked it :)
ReplyDeletevery 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) :)
ReplyDeletehttp://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;
}
can u write in c
ReplyDelete