Squares of a Sorted Array LT977

Given an array of integers A sorted in non-decreasing order, return an array of the squares of each number, also in sorted non-decreasing order.

Example 1:

Input: [-4,-1,0,3,10]
Output: [0,1,9,16,100]

Example 2:

Input: [-7,-3,2,3,11]
Output: [4,9,9,49,121]

Note:

  1. 1 <= A.length <= 10000
  2. -10000 <= A[i] <= 10000
  3. A is sorted in non-decreasing order.

Since the arry is non-decreasingly sorted, we can use two pointers, either both pointers start from the middle, the negative one goes to the left and the non-negative goes to the right, as the magnitude of numbers increase from the middle, 

result[dest++] = A[positive++] if Math.abs(A[negative]) <= Math.abs(A[positve])

result[dest++] = A[negative--] otherwise

Be careful: postive < A.length && negative >= 0, also need to deal with cases when there are more negative or positve left, copy the leftover to the result array.

Time complexity: O(n) two passes

Space complexity: O(n) to store result

class Solution {
    int findNonNegativeIndex(int[] A) {
        int index = 0;
        while( index < A.length && A[index] < 0) {
            ++index;
        }
        return index;
    }
    public int[] sortedSquares(int[] A) {
        int sz = A.length;
        int[] result = new int[sz];
        
        int nonNegative = findNonNegativeIndex(A);
        int negative = nonNegative - 1;
        int destination = 0;
        
        while(nonNegative < sz && negative >= 0) {
            if(Math.abs(A[negative]) >= Math.abs(A[nonNegative])) {
                result[destination++] = A[nonNegative] * A[nonNegative];
                ++nonNegative;
            }
            else {
                result[destination++] = A[negative] * A[negative];
                --negative;
            }
        }
        
        while(nonNegative < sz) {
            result[destination++] = A[nonNegative] * A[nonNegative];
            ++nonNegative;
        }
        
        while(negative >= 0) {
            result[destination++] = A[negative] * A[negative];
            --negative;
        }
        
        return result;
    }
}

Another way, the two pointers start from two ends and walk towards to each other. Save the effort to deal with the extra cases caused by boundary and also the effor to find the divider between positive and negative numbers.

Time complexity: O(n) one pass

Space complexity: O(n) to store result

class Solution {
    public int[] sortedSquares(int[] A) {
        int sz = A.length;
        int[] result = new int[sz];
        
        for(int left = 0, right = sz-1, destination = sz-1; left <= right; ) {
            if(Math.abs(A[left]) >= Math.abs(A[right])) {
                result[destination] = A[left] * A[left];
                ++left;
                --destination;
            }
            else {
                result[destination] = A[right] * A[right];
                --right;
                --destination;
            }
        }
        
        return result;
    }
}

use the destination index as check condition, slightly more concise

class Solution {
    public int[] sortedSquares(int[] A) {
        int sz = A.length;
        int[] result = new int[sz];
        
        for(int left = 0, right = sz-1, destination = sz-1; destination >= 0; --destination) {
            if(Math.abs(A[left]) >= Math.abs(A[right])) {
                result[destination] = A[left] * A[left];
                ++left;
            }
            else {
                result[destination] = A[right] * A[right];
                --right;
            }
        }
        
        return result;
    }
}

猜你喜欢

转载自www.cnblogs.com/taste-it-own-it-love-it/p/10363781.html
今日推荐