Hi there! I am sharing my full thinking process under time pressure and solution. The resultant array elements must be all the same. Let's say some integer k, so final array looks like [k,k,k,...,k]. The number of moves to get that array can be calculated by, moves = |k - a1| + |k-a2| + ...+|k-ai|+...+|k-an|. Note that some elements are greater than k and some elements are less. Thus, it worth to know the number of elements that are less than k, and the number of elements that are greater that k. If know them we can reformulate the equation as moves = Nless*k - sumLess +sumGreater-Ngreater*k. Now the equation gets more "programmable", and we have to search for such k, that minimizes value of moves. It is obvious that k must be selected among the original array elements, because it reduces the number of operations at least by one. Thus, we came up with an idea. For each element in array calculate moves, then select minimum among them. Now, we see another problem, how to calculate them number of elements that are less than k and their sum? The same problem occurs for greater elements. Naive solution is to calculate number of smalles elements and greater elements along with their sum for each element of the array seperately. That would give us solution with O(n^2) time complexity.

Can we do better? Yes we can, if we sort out the original array first, we can immediately know both the number of elements that are less than the current element and the number of elements that are greater that the current element. In addition we have to know total sum of elements and sum of elements before each element. Finally we came up with O(nlog(n)) time and O(1) space solution! Below is the code for that solution:

```
public class Solution {
public int minMoves2(int[] nums) {
if(nums==null|| nums.length==0) return 0;
long moves = Integer.MAX_VALUE;
Arrays.sort(nums);
long totalSum = 0L;
long sum = 0L;
for(int i =0;i<nums.length;i++){
totalSum += (long)nums[i];
}
for(int i =0;i<nums.length;i++){
long m = (long)(i-(nums.length-i-1)-1)*(long)nums[i]-sum+(totalSum-sum);
moves = Math.min(m, moves);
sum+=nums[i];
}
return (int)moves;
}
}
```

Can we do better? Yes, we can! Let's think about k. Intuitively that value must be the median element in the original sorted array. Proof of that fact is simple, just look at our equation moves = numLess*k-sumLess + sumGreater - numGreater*k. Let's take derivative from that function by k. dmoves/dk = numLess-numGreater. The moves becomes minimum when the derivative is zero, so numLess-numGreater = 0 or numsLess = numGreater. Which is possible only when the element is the median element. We can find k in O(1) time. Instead of brute forcing all elements in the array we just consider the middle element in the sorted array. Despite generally the time complexity remains being O(nlog(n)), due to sorting, it improves performance very much. Further it can be optimized up to O(n), by using Quick select algorithm, and you can find this solution here

```
public class Solution {
public int minMoves2(int[] nums) {
if(nums==null|| nums.length==0) return 0;
long moves = Integer.MAX_VALUE;
Arrays.sort(nums);
long totalSum = 0L;
long sum = 0L;
for(int i =0;i<nums.length;i++){
totalSum += (long)nums[i];
if(i<nums.length/2) sum+=(long)nums[i];
}
int k = nums.length/2;
moves = (long)(k-(nums.length-k-1)-1)*(long)nums[k]-sum+(totalSum-sum);
return (int)moves;
}
}
```

P.S: I have demonstrated the calculation of moves to be understandable, that is why it looks poor. Also be careful with shortening equation for moves in the first code. Because it may exceed the integer range if not to be careful with multiplications. Sorry for poor code.