A counting technique for an apparent intractable problem
The following problem is a variation
of a hacker-rank problem (this one: https://www.hackerrank.com/challenges/picking-numbers).
Given a set of M numbers (M ~= 10,000) and a number N (say N = 5), write an
algorithm to find the largest set amongst the M numbers such that the
difference between any element of that subset is less than N. For example, if
the set of M numbers is {1, 2, 3, 7} and N = 3, then the largest set that
matches the criteria defined would be {1, 2, 3}. Notice that the difference
between any of these numbers is always less than 3 (also, you may assume the
numbers of the set M are within a known range, say M[i] in [1,1000]).
There is a linear
solution to this problem using constant memory, but let’s first analyze the
not-so-optimal solutions. Testing subsets by subsets is clearly intractable
given that the number of subsets for a set of 10,000 elements is a massive number. Another solution
could be to sort the set and then for each element get the largest subset by
traversing the sorted set with 2 nested loops. It might be a feasible approach,
with a pros of constant memory, however the big-O time expectation is still
quite large: NLogN (the sorting) + N^2 (the two nested loops), which yields
O(100,000,000). Certainly doable in a reasonable laptop, but still the moment
that we move the M by one extra zero (M=100,000) it becomes intractable, so I
consider this solution very limited.
The key to solve
this problem in linear time and constant memory is the somewhat casual comment
towards the end of the problem statement: “Also,
you may assume the numbers of the set M are within a known range, say M[i]
in [1,1000].”. That innocent statement unlocks the key to solve the
problem in linear time with constant memory.
Given
that the numbers will all fall within a fixed range, between 1 and 1000, we can
count all the occurrences of these
numbers by using an integer array of length 1000 (call this array S). Then, let’s
think about the core of the problem: find the largest subset of numbers whose
difference between any element is < N. Well, when we look at the array S,
like pick an index within this array say index 4, one possible solution are all
the numbers that fall into positions S[4], S[5], S[6], S[7] and S[8]. All these
numbers differ by less than 5. We can do that for all the indexes in the array
S, and for each index check the partial solution for the N consecutive indexes,
and keep track of the max number of elements. That’s it! This loop only takes
1000*N, and the memory is constant (1000).
Let’s come
up with the final big-O for this algorithm: M (initial parsing adding the
numbers to S) + 1000*N. Since we assume that M >> N, then we have a final
time complexity of O(M).
The image below is an explanation of the code to solve the problem, and the actual code is down below for reference. Counting techniques like this one are commonly used when the problem is constrained to finite and small ranges. Cheers, Marcelo.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution
{
static void Main(String[] args)
{
int n = 1000;
int m = 10000000;
int[] randomNumbers = new int[m];
int minRange = 1;
int maxRange = 10000;
Random rd = new Random();
for (int i = 0; i < randomNumbers.Length; i++)
randomNumbers[i] = rd.Next(minRange, maxRange + 1);
int[] slots = new int[maxRange + 1];
for (int i = 0; i < randomNumbers.Length; i++)
slots[randomNumbers[i]]++;
int maxSetOfNumbers = 0;
int solutionIndex = 0;
for (int i = 0; i < slots.Length - n; i++)
{
int partialSum = 0;
for (int j = 0; j < n; j++)
partialSum += slots[i + j];
if(partialSum > maxSetOfNumbers)
{
maxSetOfNumbers = partialSum;
solutionIndex = i;
}
}
Console.WriteLine("Max set of numbers: {0}", maxSetOfNumbers);
/* debug only
Console.Write("Numbers: ");
for (int i = 0; i < n; i++)
for (int j = 0; j < slots[solutionIndex + i]; j++)
Console.Write("{0} ", solutionIndex + i);
Console.WriteLine();
*/
}
}
well done, Marcelo! When solving a hackerrank problem I actually didn't even bother to use count sort and used a regular sort, but there is really no need to have 2 nested loops with O(N^2) complexity to find the largest subset - there is only one loop necessary to update start and end indices of a window containing elements satisfying a problem requirement.
ReplyDeleteSolution to a hackerrank problem is below (http://ideone.com/SPt4H9):
#include
#include
#include
using namespace std;
int main() {
int n; cin >> n;
vector numbers(n);
for (int i = 0; i < n; ++i) cin >> numbers[i];
sort(numbers.begin(), numbers.end());
int start = 0;
int end = 0;
int length = 0;
int max_length = length;
while (start <= end && end < n) {
if (numbers[end] - numbers[start] <= 1) {
length += 1;
end += 1;
max_length = max(max_length, length);
} else {
length -= 1;
start += 1;
}
}
cout << max_length << endl;
return 0;
}
In order to solve a more generic problem, all we need is to change difference variable value.
Well done...!
ReplyDeleteāļāļēāļāļēāļĢ่āļēāļāļāļāđāļĨāļ์
āļีāļāļĨัāļ
āļĢ้āļāļĒāđāļŦāļĄ
ReplyDeleteāļĢ้āļāļĒāđāļŦāļĄāļāļĢัāļāļĢูāļāļŦāļ้āļē āļāļĢัāļāļĢูāļāļŦāļ้āļēāļี่āđāļŦāđāļāļี āļĢ้āļāļĒāđāļŦāļĄāļี่āđāļŦ่āļāđāļŦāļāļี? āļัāļāļัāļĄāļŠāļāļēāļāļāļĒāļēāļāļēāļĨāđāļ็āļāļāļģāļāļāļāđāļĄ่āļ§่āļēāļāļ°āđāļ็āļ āļĢ้āļāļĒāđāļŦāļĄāļŦāļ้āļēāđāļĢีāļĒāļ§ āđāļ็āļāļ§ีāđāļĨāļ์āđāļāļāļāļĢāļ°āđāļāļĻāđāļāļēāļŦāļĨีāļ้āļ§āļĒāđāļŦāļĄāļ้āļēāļ āđāļŦ้āļ่āļēāļāļāļēāļĄāđāļāļāļāļĢāļ°āđāļāļĻāđāļāļēāļŦāļĨี āļĨāļāļāļēāļĒุ āļŦāļ้āļēāđāļ็āļ āđāļĄ่āđāļ็āļ āđāļĄ่āļāļāļāļ้āļģ āđāļĄ่āļāļ§āļĄ āļŦāļ้āļēāđāļ็āļāļ§ีāđāļāļ āļĨāļāđāļŦāļีāļĒāļ āđāļŦāļีāļĒāļāļāļĢāļ°āļัāļāļŠāļĄāļāļĢāļēāļĢāļāļāļēāļĢ้āļāļĒāđāļŦāļĄ
āļĢ้āļāļĒāđāļŦāļĄāļŦāļ้āļēāđāļĢีāļĒāļ§
āļĢ้āļāļĒāđāļŦāļĄ āļ§ีāđāļāļ
āļĢ้āļāļĒāđāļŦāļĄāļ้āļēāļāļāļĨāļē
4 āļุāļāđāļ่āļāļāļāļāļāļēāļĢāđāļĨืāļāļāļĨ่āļāđāļāļĄ āļŠāļĨ็āļāļ pussy888
ReplyDeleteāļŠāļģāļŦāļĢัāļāļู้āļี่āļื่āļāļāļูāļāđāļāļāļēāļĢāđāļĨ่āļāđāļāļĄāļāļēāļŠิāđāļāļāļāļāđāļĨāļ์ āđāļĨāļ°āļ็āļูāđāļāļĄāļāļŠิāđāļāļāļāļāđāļĨāļ์ āđāļิāļāđāļĢื่āļāļāđāļĄ่āļี āđāļĄ่āļŠāļĄāļāļ§āļĢāļี่āļāļ°āđāļ้āļēāļĄāļēāđāļĨ่āļ āļāļģāđāļ็āļāļ้āļāļāļāļĨ่āļēāļ§āļ§่āļē āđāļāļŠāļģāļŦāļĢัāļāļāļēāļāļุāļāļāļĨāđāļĨ้āļ§ āļāļēāļĢāđāļĨ่āļāđāļāļĄāļāļēāļŠิāđāļāļāļāļāđāļĨāļ์āļŠāļĨ็āļāļ pussy888 āļāļēāļāļีāļ็āļāļēāļāļāļ°āđāļ็āļāļีāļāļŦāļึ่āļāļัāļ§āļ่āļ§āļĒ āļีāļāļŦāļึ่āļāļŦāļāļāļēāļāļŠāļģāļŦāļĢัāļāđāļāļāļēāļĢāļāļģāđāļิāļāļี่āļŠāļēāļĄāļēāļĢāļāļāļ°āļ่āļ§āļĒāđāļŦ้āļู้āđāļĨ่āļāđāļāļĄ āļŠāļēāļĄāļēāļĢāļāļŦāļēāđāļิāļāđāļิ่āļĄāđāļŦ้āļัāļāļāļĢāļāļāļāļĢัāļ§āļāļāđāļāļāđāļŦ้āļĄีāļีāļ§ิāļāļี่āļีāļĒิ่āļāļึ้āļāđāļ้ āđāļāļĢāļēāļ°āļāļ°āļั้āļāđāļื่āļāđāļĄ่āđāļŦ้āļāļģāđāļิāļāļัāļāļŦāļēāļāļēāļĄāļĄāļē āļู้āđāļĨ่āļāđāļāļĄāļ็āđāļĨāļĒāļāļģāđāļ็āļāļ้āļāļāđāļĢีāļĒāļāđāļāļ§āļāļēāļāļāļēāļĢāđāļĨ่āļāđāļāļĄāļāļēāļŠิāđāļāļāļāļāđāļĨāļ์āđāļŦ้āđāļ้āļēāđāļ āđāļĨāļ°āļ็āđāļĨืāļāļāđāļĨ่āļāđāļāļĄāļāļēāļŠิāđāļāļŠāļĨ็āļāļ pussy888 āļี่āđāļŦāļĄāļēāļ°āļŠāļĄāļัāļāļāļāđāļāļ āļ็āđāļĨāļĒāļāļ°āļ่āļ§āļĒāđāļิ่āļĄāļัāļāļŦāļ§āļ°āļŠāļģāļŦāļĢัāļāļāļēāļĢāļāļģāđāļิāļāđāļ้āļĄāļēāļāļึ้āļ āđāļĨ้āļ§āļ็āļ้āļēāđāļิāļāļุāļāļĒāļāļĨัāļāđāļĨāļี่āļāļ°āđāļ้āļēāļĄāļēāđāļĨ่āļāđāļāļĄāļāļēāļŠิāđāļāļāļāļāđāļĨāļ์ āļŠāļēāļĄāļēāļĢāļāđāļ้āļēāļĄāļēāļĄāļāļ 4 āļุāļāđāļ่āļāļāļāļāļāļēāļĢāđāļĨ่āļāđāļāļĄāļāļēāļŠิāđāļāļāļāļāđāļĨāļ์āļŠāļĨ็āļāļ pussy888 āļี่āļāļ§āļāđāļĢāļēāđāļ้āļัāļāđāļāļāđāļ§้āđāļŦ้āļ่āļēāļāļี้ āļ้āļģāļāļĢāļ°āļัāļāđāļ้āđāļĨāļĒāļ§่āļē āļĄัāļāļāļ°āļ่āļ§āļĒāļāļģāđāļŦ้āļĢāļ°āļุāļĢāļāļāļĨāļāđāļāđāļ้āļēāļĄāļēāđāļĨ่āļāļāļĄāļāļēāļŠิāđāļ āļŠāļĨ็āļāļ pussy888 āđāļ้āļ่āļēāļĒāļĄāļēāļāļĒิ่āļāļāļ§่āļēāđāļิāļĄ
4 āļุāļāđāļ่āļāļี่āļุāļāļāļģāļ้āļāļāļāļĢāļēāļāļ่āļāļāđāļ้āļēāļĄāļēāđāļĨ่āļāđāļāļĄāļŠāļĨ็āļāļ pussy888
āļ§ัāļāļี้āļāļ§āļāđāļĢāļēāļāļ°āļāļēāļุāļāđāļāļู 4 āļุāļāđāļ่āļāļāļāļāļāļēāļĢāđāļĨืāļāļāđāļ้āļēāļĄāļēāđāļĨ่āļāđāļāļĄāļŠāļĨ็āļāļ pussy888 āļึ่āļāļ็āļāļŦāļึ่āļāđāļāđāļāļĄāļāļēāļŠิāđāļāļāļāļāđāļĨāļ์āļĒāļāļāļŪิāļ āđāļĨāļ°āļ็āđāļ็āļāļี่āļāļāļāđāļ āļāļāļāđāļŦāļĨ่āļēāļัāļāđāļĨ่āļāđāļāļĄāļĄāļēāļāļĄāļēāļĒāļ่āļēāļĒāļāļāļ āļ้āļēāļŦāļēāļāļ้āļāļāļāļēāļĢāļĢูāđāļĨ้āļ§āļ§่āļēāļุāļāđāļ่āļāļี่āļ§่āļēāļั้āļ āđāļ็āļāļāļĒ่āļēāļāđāļĢ āļāļēāļĄāļāļ§āļāđāļĢāļēāđāļāļูāļัāļāđāļ้āđāļĨāļĒ
• āđāļāļĄāļŠāļĨ็āļāļ pussy888 āđāļ็āļāđāļāļĄāļāļēāļŠิāđāļāļāļāļāđāļĨāļ์āļี่āđāļĨ่āļāļ่āļēāļĒ āđāļāļĒāđāļŦāļุāļี้āļ้āļēāđāļิāļāļĨุāļāļĢāđāļĄ่āđāļāļĒāđāļĨ่āļāđāļāļĄāļāļēāļŠิāđāļāļāļāļāđāļĨāļ์āļĄāļēāļ่āļāļ āļŦāļĢืāļāļĒัāļāđāļĄ่āļĄีāļāļ§āļēāļĄāļĢู้āđāļี่āļĒāļ§āļัāļāđāļāļĄāļāļēāļŠิāđāļāļĄāļēāļ่āļāļāļ็āļŠāļēāļĄāļēāļĢāļāđāļĨ่āļāđāļāļĄāļŠāļĨ็āļāļ pussy888āđāļ้ āđāļĄ่āļāļģāđāļ็āļāļี่āļāļ°āļ้āļāļāļĄāļēāļ§ิāļāļāļัāļāļ§āļĨāļŦāļĢืāļāļāļĨุ้āļĄāđāļ
• āļุāļāļŠāļēāļĄāļēāļĢāļāđāļĨืāļāļāļ่āļēāļĒāđāļิāļāđāļิāļĄāļัāļāđāļ้āđāļāļāļāļēāļĄāļāļĢāļēāļĢāļāļāļē āđāļื่āļāļāļāļēāļāļ§่āļēāđāļāļĄ āļŠāļĨ็āļāļ pussy888 āđāļĄ่āļāļģāļัāļāđāļิāļāļŠāļģāļŦāļĢัāļāđāļื่āļāļāļēāļĢāļ§āļēāļāđāļิāļĄāļัāļ āļāļģāđāļŦ้āļู้āđāļĨ่āļāđāļāļĄāļŠāļēāļĄāļēāļĢāļāļāļģāļัāļāļ§āļāđāļิāļāļี่āđāļāļēāļĄāļēāđāļĨ่āļāđāļāļĄāļāļēāļŠิāđāļāļāļāļāđāļĨāļ์āļี้āđāļ้
• āļĄีāļ§ิāļีāļāļēāļĢāļŠāļģāļŦāļĢัāļāļāļēāļĢāđāļĨ่āļāđāļāļĄ āļŠāļĨ็āļāļ pussy888 āļŦāļĨāļēāļĒāđāļāļ āļึ่āļāļāļ°āļ่āļ§āļĒāđāļิ่āļĄāļัāļāļŦāļ§āļ°āļŠāļģāļŦāļĢัāļāđāļāļāļēāļĢāļāļģāđāļิāļāđāļŦ้āļัāļāļู้āđāļĨ่āļāđāļ้āļāļĒ่āļēāļāļีāđāļĒี่āļĒāļĄ āļāļģāđāļŦ้āļĄีāļāļāļี่āļāļāđāļāđāļ้āļēāļĄāļēāđāļĨ่āļāđāļāļĄāļāļēāļŠิāđāļāļŠāļĨ็āļāļ pussy888āđāļิ่āļĄāļึ้āļāđāļĢื่āļāļĒāđ
• āļู้āđāļĨ่āļāđāļāļĄāđāļ้āđāļāļāļēāļŠāļāļģāđāļิāļāđāļ้āļ่āļēāļĒ āļ้āļ§āļĒāļĢāļ°āļāļāđāļāļĄāļี่āļāļĢัāļāļāļĢุāļāļึ้āļ āļāļģāđāļŦ้āļู้āđāļĨ่āļāđāļāļĄāļĄีāļĢāļēāļĒāđāļ้ āļĢāļ§āļĄāļั้āļāđāļ้āđāļāļāļēāļŠāļี่āļāļ°āļูāļāđāļ็āļāļāļāđāļีāļĒāļāļāđāļāļĄāļŠāļĨ็āļāļ pussy888āļĄāļēāļāļĒิ่āļāļāļ§่āļēāđāļิāļĄ
āđāļีāļĒāļāđāļ่āļēāļี้ āļĄั่āļāđāļāļ§่āļēāļŦāļĨāļēāļĒāļ่āļēāļāļี่āļāļģāļĨัāļāļāļāļĨāļāđāļāļ§่āļēāļāļ°āđāļ้āļēāļĄāļēāđāļĨ่āļāđāļāļĄāļŠāļĨ็āļāļ pussy888āļีāļŦāļĢืāļāđāļāļĨ่āļē āļ็āļāļēāļāļāļĢั้āļāļāļēāļāļāļ°āļāļāļĨāļāđāļāđāļĨ้āļ§ āļึ่āļāļ้āļēāđāļิāļāļุāļāļāļāļĨāļāđāļāļี่āļāļ°āļĒāļēāļĄāđāļ้āļēāļĄāļēāļāļāļĨāļāļāđāļĨ่āļāđāļāļĄāļāļēāļŠิāđāļāļāļāļāđāļĨāļ์āļี้āļĄāļāļ āļāļĒ่āļēāļĨืāļĄāļี่āļāļ°āļĢāļ°āļ§ัāļ āļĢāļ§āļĄāļั้āļāđāļĨืāļāļāđāļĨ่āļāđāļāļĄāļŠāļĨ็āļāļ pussy888āļāļĒ่āļēāļāļĄีāļŠāļิāļŠัāļĄāļāļัāļāļāļ° āļิāļāđāļŦ้āļี่āļ้āļ§āļāļ่āļāļāļāļ°āļ่āļēāļĒāđāļิāļāļāļัāļ āļŦāļĢืāļāđāļĢิ่āļĄāļāļัāļ āļĻึāļāļĐāļēāđāļĨ่āļēāđāļĢีāļĒāļāđāļāļ§āļāļēāļāļāļēāļĢāđāļĨ่āļāđāļāļĄāđāļŦ้āļĢู้āđāļĢื่āļāļ āđāļĨ้āļ§āļ็āđāļŦ้āļāļēāļัāļāļāļēāļĢāđāļิ่āļĄāļึ้āļāđāļĢื่āļāļĒāđ āļŠāļĢุāļāđāļ็āļ āļู้āđāļĨ่āļāđāļāļĄāļึāļāļāļ§āļĢāđāļĢีāļĒāļāļĢู้āđāļāļĢีāļĒāļĄāļāļ§āļēāļĄāļāļĢ้āļāļĄāđāļĨ่āļāđāļāļĄāļāļēāļŠิāđāļāļāļāļāđāļĨāļ์āļāļāļāļัāļ§āļุāļāđāļāļāđāļŦ้āļีāđāļĒี่āļĒāļĄāļี่āļŠุāļ āđāļื่āļāļāļ§āļēāļĄāļāļĢāļ°āļŠāļāļāļ§āļēāļĄāļŠāļģāđāļĢ็āļāļŠāļģāļŦāļĢัāļāđāļāļāļēāļĢāđāļĨ่āļāļāļāļāļēāļŠิāđāļāļāļāļāđāļĨāļ์āļāļāļุāļāļāļ
pussy888