First of all, I will not delve into the question whether you are allowed to call library sort or not. This is up to you and your professor/boss/task.
Instead, I will delve into the question of whether you should do it. Imagine a case when you have 1 000 000 items in your array. The initial sort only has an O(n * log(n)) complexity (where n represents the number of items in your array), which is a high cost. Additionally, you have an O(m) complexity after the sort to calculate the sum of the first/last m elements, depending on the direction of the sort (where m represents the number of items to sum), so, in total, the complexity is of
O(m + n * log(n))
Below I describe my initial approach, and then an improvement, suggested by @Elliott in the comment section.
1. Taking the first n item
Create an array, let's call it output (and the input will be called input here). Copy the first n (unsorted) elements from input into output.
2. Sort output
Yes, this is an algorithm of nlog(n) complexity, but your output is likely to be much smaller than your input.
3. Continue the loop
Continue looping your input from the (n+1)th element and for each element compare it with the smallest element in output (this is why we sorted output). If the smallest element of output is greater than the current element, then do nothing in this iteration. Otherwise find the greatest element of output that is still smaller than the current element, shift everything smaller to the left in output and put the current element into its right place.
Example logic in Javascript
function(item, output) {
let highestIndex = -1;
while ((output[highestIndex + 1] < item) && (highestIndex + 1 < output.length)) highestIndex++;
if (highestIndex >= 0) {
for (let index = 0; index < highestIndex; index++) output[index] = output[index + 1];
output[highestIndex] = item;
}
}
4. Take into account edge cases
- if n is 0, then the result is 0, no need for any loop
- if n equals the length of
input, then just sum input
- if n is negative or greater than the length of
input, throw an error
These edge cases are important, you can easily increase performance for them.
Improvement based on Elliott's suggestion
Even though it is probable that the number of elements to sum will frequently be of low value, in the case when there are many items to sum, my initial approach, described in earlier sections can contribute to the complexity and there is further room for improvement.
As Elliott, quite correctly pointed out, my stack-based approach has a linear complexity (if the number of elements to sum can be great) and he also suggested an improvement, which is to use an AVL tree to store the highest numbers so far.
If that approach would be taken, then the idea would change the way we handle the greatest numbers found so far. Whenever we process a new element, we could search for it in the AVL tree (O(log(m)) complexity), removing the smallest element (if the new element is greater), adding the new element and inserting the new element into this self-balancing tree.
This is a more complicate, but more efficient approach, that is, it is less complex in time than the one I initially proposed. Thanks, Elliott for the suggestions for improvement!