Complexity is a difficult beast to master, because it is polymorphic.
When we speak about the complexity of an algorithm, we generally simplify it and express it according to what we think being the bottleneck operation.
For example, when evaluating sorting algorithms, the complexity is expressed as the number of comparisons; however, should your memory be a tape1 instead of RAM, the true bottleneck is the memory access and therefore a quicksort O(N log N) ends up being slower than a bubblesort O(N ** 2).
Here, your algorithm may be optimal, its implementation seems lacking: there is a lot of memory allocation/deallocation going on, for example. Therefore, it may well be that you did not identified the bottleneck operation correctly, and that all talk of linear complexity are moot since you are not measuring the right things.
1 because tapes take a time to move from one cell to another proportional to the distance between those cells, and thus a quicksort algorithms that keep jumping around memory ends up doing a lot of back and forth whilst a bubble sort algorithm just runs the length of the tape N times (max).