# Now, Sorted Squared Array: Problem Statement

``````Write a function that takes in a non-empty array of integers that are sorted
in ascending order and returns a new array of the same length with the squares
of the original integers also sorted in ascending order.

Sample Input
array = [1, 2, 3, 5, 6, 8, 9]

Sample Output
[1, 4, 9, 25, 36, 64, 81]
``````

# Note: See hints only if you are unable to solve the problem at least twice. Be astute.

``````Hint 1:
While the integers in the input array are sorted in increasing order, their
squares won't necessarily be as well, because of the possible presence of
negative numbers.

Hint 2:
Traverse the array value by value, square each value, and insert the squares
into an output array. Then, sort the output array before returning it. Is this
the optimal solution?

Hint 3:
To reduce the time complexity of the algorithm mentioned in Hint #2, you need
to avoid sorting the output array. To do this, as you square the values of the
input array, try to directly insert them into their correct position in the
output array.

Hint 4:
Use two pointers to keep track of the smallest and largest values in the input
array. Compare the absolute values of these smallest and largest values,
square the larger absolute value, and place the square at the end of the
output array, filling it up from right to left. Move the pointers accordingly,
and repeat this process until the output array is filled.``````

# UnitTest.py

``````import SortedSquaredArray as program
import unittest

class TestProgram(unittest.TestCase):

def test_case_1(self):
output = program.sortedSquaredArray([-2,1,2,3,4])
# This should return True
self.assertTrue(output == [1, 4, 4, 9, 16])

def test_case_2(self):
output = program.sortedSquaredArray2([-2,1,2,3,4])
# This should return True
self.assertTrue(output == [1, 4, 4, 9, 16])

def test_case_3(self):
output = program.sortedSquaredArray2([1, 2, 3, 5, 6, 8, 9])
# This should return True
self.assertTrue(output == [1, 4, 9, 25, 36, 64, 81])

def test_case_4(self):
output = program.sortedSquaredArray2([2])
# This should return True
self.assertTrue(output == [4])

if __name__ == '__main__':
unittest.main()
``````

# 2 approaches applied: using 1 pointer and using 2 pointers

``````# First Approach: Using 1 pointer
def sortedSquaredArray(array):
"""This function will return the sorted squared array. e.g. [-5, -2, 2, 6] --> [4, 4, 25, 36]"""
# @Author: Anish Arya
# Time Complexity: O(nlogn)
# Space Complexity O(n), where n is the size of the input array

array_copy = array.copy()
for idx in range(len(array_copy)):
array_copy[idx] = array_copy[idx] ** 2
return sorted(array_copy)
``````

# Date 10th July, 2022

2 approaches applied: using 1 pointer and

# using 2 main pointers

``````# Second Approach: Using 2  main pointers
def sortedSquaredArray2(array):
# @Author: Anish Arya
# Time Complexity: O(n)
# Space Complexity: O(n)

sortedArray = [None for _ in array] # placeholder for sorted array
end = sortedIdx = len(array) - 1
front = 0
valueToBeSquaredAndStored = None
# maintaining 3 ptrs for comparing absolute values of front and end
# of the sorted input array to keep track of smallest and largest value and the remaining 1 ptr for storing the
# sorted squared value in the end of the Sorted Array.
# Compare array[front] and array[end], then, store the store
# the max absolute element's squared value to the last element and move the ptrs accordingly
while front <= end:
if abs(array[front]) > abs(array[end]):
valueToBeSquaredAndStored = array[front]
front += 1
else:
valueToBeSquaredAndStored = array[end]
end -= 1
sortedArray[sortedIdx] = valueToBeSquaredAndStored ** 2
sortedIdx -= 1
return sortedArray
``````