If in MedianOf3 method: //swap pivot element to the second to last position
swap(arr, middle, end-1)
Then in the partition method, before return leftPtr, it needs to swap the the pivot from second to last position back to the leftPtr position.
Swap(arr, leftPtr, end-1);
After switching it back, the pivot element at that position will not change any more. It is the final position for that element.
So quicksort(arr, beginning, partition) can be changed to quicksort(arr, beginning, partition -1 ) because the element at partition position will not change any more. It doesn't need to sort that element
This method is explained in the Robert Lafore's Data Structures and Algorithms in Java book.