Skip to content

Commit 3a802dd

Browse files
committed
feat(algorithms, arrays): sorted squared array
Adds the algorithm for handling the sorted square array problem where an input of integers is used as an input to the function and the output result is the squares of each value in ascending order. The assumption made here is that the input array is in ascending order and that the integers can be negative, meaning that the order of the squares will be the same as the input array elements that generated the squares i.e. the positions might not match. This uses a two pointer approach to ensure that the resultant array is in order. The two pointer approach as the benefit of using less time to handle sorting as sorting is not done in this approach. However a new array is created which incurs a cost of O(n) where n is the size of the input array.
1 parent 905a366 commit 3a802dd

File tree

3 files changed

+150
-0
lines changed

3 files changed

+150
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Sorted Squared Array
2+
3+
Write a function that takes in a non-empty array of integers that are sorted
4+
in ascending order and returns a new array of the same length with the squares
5+
of the original integers also sorted in ascending order
6+
7+
```plain
8+
Sample Input
9+
10+
array = [1, 2, 3, 5, 6, 8, 9]
11+
12+
Sample Output
13+
14+
[1, 4, 9, 25, 36, 64, 81]
15+
```
16+
17+
## Hints
18+
19+
1. While the integers in the input array are sorted in increasing order, their
20+
squares won't necessarily be as well, because of the possible presence of
21+
negative numbers
22+
2. Traverse the array value by value, square each value, and insert the squares
23+
into an output array. Then, sort the output array before returning it. Is this
24+
the optimal solution?
25+
3. To reduce the time complexity of the algorithm mentioned in Hint #2, you need
26+
to avoid sorting the ouput array. To do this, as you square the values of the
27+
input array, try to directly insert them into their correct position in the
28+
output array.
29+
4. Use two pointers to keep track of the smallest and largest values in the input
30+
array. Compare the absolute values of these smallest and largest values,
31+
square the larger absolute value, and place the square at the end of the
32+
output array, filling it up from right to left. Move the pointers accordingly,
33+
and repeat this process until the output array is filled.
34+
35+
## Optimal Space & Time Complexity
36+
37+
- Time complexity: O(n)
38+
- Space complexity: O(n)
39+
40+
Where n is the length of the input array
41+
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from typing import List
2+
3+
4+
def sorted_squared_array(array: List[int]) -> List[int]:
5+
"""
6+
Takes in a sorted array and returns a new array with the values squared and sorted in ascending order.
7+
Args:
8+
array (List[int]): A sorted array of integers.
9+
Returns:
10+
List[int]: A new array with the values squared and sorted in ascending order.
11+
"""
12+
n = len(array)
13+
if n == 0:
14+
return []
15+
# the result array must be the same length as the input array
16+
result = [0] * n
17+
18+
# two pointers that point to the start and end of the input array to enable insertion of the squared values in
19+
# ascending order
20+
left, right = 0, n - 1
21+
22+
# file result array from right to left (largest to smallest squares
23+
for i in range(n-1, -1, -1):
24+
left_abs = abs(array[left])
25+
right_abs = abs(array[right])
26+
27+
if left_abs > right_abs:
28+
square = left_abs * left_abs
29+
result[i] = square
30+
left += 1
31+
else:
32+
square = right_abs * right_abs
33+
result[i] = square
34+
right -= 1
35+
36+
# Write your code here.
37+
return result
38+
39+
40+
def sorted_squared_array_2(array: List[int]) -> List[int]:
41+
"""
42+
Takes in a sorted array and returns a new array with the values squared and sorted in ascending order.
43+
Args:
44+
array (List[int]): A sorted array of integers.
45+
Returns:
46+
List[int]: A new array with the values squared and sorted in ascending order.
47+
"""
48+
n = len(array)
49+
if n == 0:
50+
return []
51+
# the result array must be the same length as the input array
52+
result = [0] * n
53+
54+
# two pointers that point to the start and end of the input array to enable insertion of the squared values in
55+
# ascending order
56+
left, right = 0, n - 1
57+
58+
# file result array from right to left (largest to smallest squares
59+
for i in range(n-1, -1, -1):
60+
left_square = array[left] ** 2
61+
right_square = array[right] ** 2
62+
63+
if left_square > right_square:
64+
result[i] = left_square
65+
left += 1
66+
else:
67+
result[i] = right_square
68+
right -= 1
69+
70+
# Write your code here.
71+
return result
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import unittest
2+
from . import sorted_squared_array, sorted_squared_array_2
3+
4+
5+
class SortedSquaredArrayTestCases(unittest.TestCase):
6+
def test_1(self):
7+
"""for an input of [1,2,3,5,6,8,9] it should return [1, 4, 9,25, 36, 64, 81]"""
8+
input_array = [1, 2, 3, 5, 6, 8, 9]
9+
expected = [1, 4, 9, 25, 36, 64, 81]
10+
actual = sorted_squared_array(input_array)
11+
self.assertEqual(expected, actual)
12+
13+
def test_2(self):
14+
"""for an input of [1] it should return [1]"""
15+
input_array = [1]
16+
expected = [1]
17+
actual = sorted_squared_array(input_array)
18+
self.assertEqual(expected, actual)
19+
20+
21+
class SortedSquaredArray2TestCases(unittest.TestCase):
22+
def test_1(self):
23+
"""for an input of [1,2,3,5,6,8,9] it should return [1, 4, 9,25, 36, 64, 81]"""
24+
input_array = [1, 2, 3, 5, 6, 8, 9]
25+
expected = [1, 4, 9, 25, 36, 64, 81]
26+
actual = sorted_squared_array_2(input_array)
27+
self.assertEqual(expected, actual)
28+
29+
def test_2(self):
30+
"""for an input of [1] it should return [1]"""
31+
input_array = [1]
32+
expected = [1]
33+
actual = sorted_squared_array_2(input_array)
34+
self.assertEqual(expected, actual)
35+
36+
37+
if __name__ == '__main__':
38+
unittest.main()

0 commit comments

Comments
 (0)