Exercise 1: reverse_new vs. reverse_in_place — Possible Solution ==================================================================== reverse_new(arr): O(n) AUXILIARY SPACE ------------------------------ This function builds an entirely new list to hold the reversed elements, separate from the original array. That new list's size grows directly with the input size - per this chapter's own definition, this is genuine AUXILIARY space, extra memory beyond what the input itself already occupies. Auxiliary space: O(n). reverse_in_place(arr): O(1) AUXILIARY SPACE ------------------------------ This function swaps elements directly within the existing array using two index pointers, allocating no new array at all. The only extra memory needed is a small, fixed number of variables (the two index pointers, and perhaps one temporary variable during each swap) - regardless of how large the input array is. Auxiliary space: O(1). WHY THE DIFFERENCE MATTERS ------------------------------ Both functions touch every element of the input (O(n) input space, which per this chapter's own convention isn't counted as part of either function's own complexity, since the input exists either way). The real difference is entirely in AUXILIARY space: reverse_new allocates a full second copy of the data, while reverse_in_place reuses the original array's own memory. This is exactly the kind of in-place-vs-new-allocation distinction this chapter drew between bubble sort (O(1) auxiliary space) and merge sort (O(n) auxiliary space) - the same tradeoff pattern, applied here to a much simpler operation. WHY THIS WORKS AS AN ANSWER ------------------------------ Each function's auxiliary space is determined by identifying exactly what EXTRA memory it allocates beyond the input itself, per this chapter's own input-space-vs-auxiliary-space distinction, rather than counting the input array's own size (which both functions touch equally) as part of either one's complexity.