Squares of a Sorted Array

easy Arrays

Problem

A sorted array (smallest first, it can contain negative numbers) is given. Print the squares of its numbers, also sorted from smallest to biggest. Do it in O(n) with two pointers, not by sorting again.

Constraints

  • 1 <= n <= 10^5
  • |value| <= 10^4

Examples

Input

5
-4 -1 0 3 10

Output

0 1 9 16 100

Solutions

Best approachTime O(n)Space O(n)

Sorting the squares takes O(n log n). The input is already sorted, so the squares are big at both ends and small in the middle; two pointers merge them in O(n).

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Sorted squares.
 * Input   : n, then n sorted integers.
 * Output  : n squares.
 * Approach: Two pointers.
 * Time    : O(n)
 * Space   : O(n)
 * Java    : 8 or newer.
 */
import java.util.Scanner;
import java.util.Arrays;
import java.util.stream.Collectors;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static int[] solve(int[] a) {
        // Step 1: The biggest square is at one of the two ends, because negative numbers have big squares too.
        int[] result = new int[a.length];
        int left = 0;
        int right = a.length - 1;
        // Step 2: Fill the result from the back. Always take the end with the bigger absolute value.
        for (int position = a.length - 1; position >= 0; position--) {
            if (Math.abs(a[left]) > Math.abs(a[right])) {
                result[position] = a[left] * a[left];
                left++;
            } else {
                result[position] = a[right] * a[right];
                right--;
            }
        }
        return result;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int size = scanner.nextInt();
        int[] a = new int[size];
        for (int i = 0; i < size; i++) {
            a[i] = scanner.nextInt();
        }
        System.out.println(Arrays.stream(solve(a)).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
    }
}
Hints (1)
  1. Why is the biggest square always at an end?