Shuffling chunks of ints in an array
pairs is overcomplicated indeed. Notice that a block of size k contributes k-1 pairs, and no other pair exists. So the total is a sum of (k - 1) taken over all blocks. Final observation is that the sizes of blocks add up to the size of array, therefore pairs = num.size() - blocks.size() is all you need.
shuffle can be performed in linear time (strictly speaking, in \$O(kn)\$, where k is number of blocks) in place (\$O(1)\$ space complexity). The key algorithm is known as rotate. One possible implementation is

void rotate(int[] array, int first, int mid, int last) {
    reverse(array, first, mid);
    reverse(array, mid, last);
    reverse(array, first, last);
}


There also is an arguably faster implementation, where each element is moved exactly once. Try to figure it out yourself.