I found this for loop in one of the solutions for Rotating array problem. I am not able to understand this line in the code.
public void RotateArray(int[] nums, int p)
{
var l = nums.Length;
var index = 0;
for (; (p %= l) != 0; l -= p, index += p)
{
for (int i = 0; i < p; i++)
{
var temp = nums[l - p + i + index];
nums[l - p + i + index] = nums[i + index];
nums[i + index] = temp;
}
}
}
this solution is working but not able to get the meaning of the condition in this for loop.
When a
forloop is confusing, it's sometimes helpful to replace it with awhileloop, because it has a more ordered depiction of the code execution order, i.e. you can read the code "from top to bottom" rather than having to jump around.A
forloop with a code ofcan be translated into this
while:Now let's modify your given code:
We can make it even easier on ourselves by changing a few more things:
pandlwithplacesandlengthindextooffset(you will see why)whileloop conditionaandbfor the swap indicesAll this is done to reduce the number of things we have to keep mental track of:
To understand what this does, it's best to look at an example:
What we can see is that after each outer loop, a part of the array has been successfully rotated. This is what
offset(or originallyindex) keeps track of.length(orl) keeps track of the length of the "rest" that needs a few rotations still.We can also see that the modulus operator
%is there to make sure that we keep the indices down within the array. It's clear that rotating a length-7 array by 4 would be the same as rotating it by 11, 18, 25, etc., or generally speaking, rotating an array of lengthnby(c * n) + xplaces is the same as rotating by justxplaces, which is what the modulus is for.And lastly we see that
offset/indexis basically just use to shift all activities into the region we are working on.The "difficult" part in understanding lies in proving that after each inner loop, the left "done" part has increased, and understanding why you can calculate the next
places/plike this. But mathematically proving this algorithm goes beyond the scope of this post.In general I recommend to create such visualizations as I did, which keep track of variable values and the manipulations. Do it for different values of
lengthandplaces(e.g. 7/5) to get an even better understanding.As others have pointed out, this code is very C#-unlike, where the order in which we value property of code is in general "clarity > brevity > performance" with exceptions only being made where warranted by the application.