Reputation: 11
I'm trying to redistribute the array of Integers.
The aim is: I have an array, let it be {2_000_000_000, 0}
.
I need:
My code below:
for (int i = 0; i < data.size(); i++){ //Looking for max element
if (data.get(i) > max){ //of the array
max = data.get(i); //Save max element
index = i; //Save the index of max element
}
}
data.set(index, 0); //Set max element = 0
if (index == data.size()){ //In case of end of array
initPos = 0; //position is the beginning
}else {
initPos = index + 1; //If no the end - pos is the next
}
while (max > 0){ //This block of code looks have
if (initPos == data.size()){ //a small speed
initPos = 0;
}
int oldVal = data.get(initPos);
oldVal++;
data.set(initPos, oldVal);
max--;
initPos++;
}
So the question is: the code while(max > 0)...
seems to be working slowly.
Do I need to use different structures instead of ArrayList to speed-up the distribution process?
Upvotes: 0
Views: 214
Reputation: 15247
Instead of looping max
times, I would calculate the amount to distribute to each other elements.
In exemple, in pseudo code :
data = { 0, 10, 42, 5, 3 };
max = 42; // you already calculated this, so in my example, I hardcode it.
index = 2; // same than above
data[index] = 0;
amountToDistribute = max / (data.length - 1); // 42 / 4 = 10.5, but it's floored to 10 since the division is made on integers
remaining = max % (data.length - 1); // 2 remaining
loop for i = 0 to i < data.length
{
if (i != index) // don't add to the max index
{
data[i] += amountToDistribute; //adding 10
}
}
// now let's add the 2 remaining
j = index + 1;
while (remaining-- > 0)
{
if (j >= data.length)
{
j = 0; //reset the iterator to 0 if the end was reached
}
data[j++]++; // add 1 to data[3] on first iteration, then to data[4] on the second one. It increases j too once added
}
print(data); // { 10, 20, 0, 16, 14 }
In my example, you have 42 to redistribute to the 4 other elements.
You can't redistribute 10.5 to each (I guess you have to use integer only)
Then you'll redistribute at least 10 (10.5 floored is 10, since the division is made on integers) to each elements.
Doing 42 modulo 4, written 42 % 4
gives you the rest of the division 42 / 4
, which is 2. The 2 remaining are redistribued the same way you wrote your first algorithm.
This can be tweaked so everything will be done in 1 loop. But it actually does 7 iterations (5 in the first loop, then 2 in the second one) instead of 42.
In that example, if you replace { 0, 10, 42, 5, 3 }
by { 0, 10, 4000000000 (4 billions), 5, 3 }
it will produce the same (adding 1 billion to each elements, but the max one) in 5 iteration instead of the 4 billions in your algorithm
Upvotes: 1