Climbing the Leaderboard, by HackerRank
Problem in question in this one: https://www.hackerrank.com/challenges/climbing-the-leaderboard. I won't copy/paste it here since it is too long, but it is clear that the problem statement, and constraints, are leading the algorithm towards a straightforward binary search approach. Code is below, cheers!!!
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution
{
static void Main(String[] args)
{
int n = Convert.ToInt32(Console.ReadLine());
string[] scores_temp = Console.ReadLine().Split(' ');
int[] scores = Array.ConvertAll(scores_temp, Int32.Parse);
int m = Convert.ToInt32(Console.ReadLine());
string[] alice_temp = Console.ReadLine().Split(' ');
int[] alice = Array.ConvertAll(alice_temp, Int32.Parse);
int[] rank = new int[n];
rank[0] = 1;
for (int i = 1; i < n; i++)
if (scores[i] == scores[i - 1]) rank[i] = rank[i - 1];
else rank[i] = rank[i - 1] + 1;
for (int i = 0; i < m; i++)
{
int index = BinarySearch(scores, alice[i]);
if (alice[i] >= scores[index]) Console.WriteLine(rank[index]);
else Console.WriteLine(rank[index] + 1);
}
}
static int BinarySearch(int[] scores, int aliceValue)
{
int left = 0;
int right = scores.Length - 1;
while (left < right)
{
int middle = (left + right) / 2;
if (scores[middle] == aliceValue) return middle;
else if (scores[middle] < aliceValue) right = middle - 1;
else left = middle + 1;
}
return left;
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution
{
static void Main(String[] args)
{
int n = Convert.ToInt32(Console.ReadLine());
string[] scores_temp = Console.ReadLine().Split(' ');
int[] scores = Array.ConvertAll(scores_temp, Int32.Parse);
int m = Convert.ToInt32(Console.ReadLine());
string[] alice_temp = Console.ReadLine().Split(' ');
int[] alice = Array.ConvertAll(alice_temp, Int32.Parse);
int[] rank = new int[n];
rank[0] = 1;
for (int i = 1; i < n; i++)
if (scores[i] == scores[i - 1]) rank[i] = rank[i - 1];
else rank[i] = rank[i - 1] + 1;
for (int i = 0; i < m; i++)
{
int index = BinarySearch(scores, alice[i]);
if (alice[i] >= scores[index]) Console.WriteLine(rank[index]);
else Console.WriteLine(rank[index] + 1);
}
}
static int BinarySearch(int[] scores, int aliceValue)
{
int left = 0;
int right = scores.Length - 1;
while (left < right)
{
int middle = (left + right) / 2;
if (scores[middle] == aliceValue) return middle;
else if (scores[middle] < aliceValue) right = middle - 1;
else left = middle + 1;
}
return left;
}
}
very nice! I used a built-in C++ lower_bound with reversed iterators, but your custom BinarySearch function makes implement even nicer. Way to go!
ReplyDeletehow would you do that ? would you mind posting that segment ?
DeleteThis would only work if same score from Scores exists in Alice's score, otherwise binary search would return last index of scores and return incorrect rank.
ReplyDeleteFor instance:
Consider scoreboard [100, 100, 90, 80] and Alice's score [95]
Then her rank should be 2. But since binary search can't find value 95 from the scoreboard it would return variable 'left' which at that point after while loop, it is last index '3' then returned value is rank 3 (incorrect).