📓
Algorithms
  • Introduction to Data Structures & Algorithms with Leetcode
  • Strings
    • Dutch Flags Problem
      • List Partitoning
    • Counters
      • Majority Vote
      • Removing Parentheses
      • Remove Duplicates from Sorted Array
    • Maths
      • Lone Integer
      • Pigeonhole
      • Check If N and Its Double Exist
      • Find Numbers with Even Number of Digits
    • Two Pointers
      • Remove Element
      • Replace Elements with Greatest Element on Right Side
      • Valid Mountain Array
      • Sort Array by Parity
      • Squares of a Sorted Array
      • Max Consecutive Ones
    • Sliding Window
      • Max Consecutive Ones 3
    • Stacks
      • Balanced Brackets
    • General Strings & Arrays
      • Move Zeros
      • Unique Elements
      • Merge Sorted Array
    • Matrices
      • Valid Square
      • Matrix Search Sequel
  • Trees
    • Untitled
  • Recursion
    • Introduction
    • Backtracking
      • Permutations
  • Dynamic Programming
    • Introduction
    • Minimum (Maximum) Path to Reach a Target
      • Min Cost Climbing Stairs
      • Coin Change
      • Minimum Path Sum
      • Triangle
      • Minimum Cost to Move Chips to The Same Position
      • Consecutive Characters
      • Perfect Squares
    • Distinct Ways
      • Climbing Stairs
      • Unique Paths
      • Number of Dice Rolls with Target Sum
    • Merging Intervals
      • Minimum Cost Tree From Leaf Values
    • DP on Strings
      • Levenshtein Distance
      • Longest Common Subsequence
  • Binary Search
    • Introduction
      • First Bad Version
      • Sqrt(x)
      • Search Insert Position
    • Advanced
      • KoKo Eating Banana
      • Capacity to Ship Packages within D Days
      • Minimum Number of Days to Make m Bouquets
      • Split array largest sum
      • Minimum Number of Days to Make m Bouquets
      • Koko Eating Bananas
      • Find K-th Smallest Pair Distance
      • Ugly Number 3
      • Find the Smallest Divisor Given a Threshold
      • Kth smallest number in multiplication table
  • Graphs
    • Binary Trees
      • Merging Binary Trees
      • Binary Tree Preorder Traversal
      • Binary Tree Postorder Traversal
      • Binary Tree Level Order Traversal
      • Binary Tree Inorder Traversal
      • Symmetric Tree
      • Populating Next Right Pointers in Each Node
      • Populating Next Right Pointers in Each Node II
      • 106. Construct Binary Tree from Inorder and Postorder Traversal
      • Serialise and Deserialise a Linked List
      • Maximum Depth of Binary Tree
      • Lowest Common Ancestor of a Binary Tree
    • n-ary Trees
      • Untitled
      • Minimum Height Trees
    • Binary Search Trees
      • Counting Maximal Value Roots in Binary Tree
      • Count BST nodes in a range
      • Invert a Binary Tree
      • Maximum Difference Between Node and Ancestor
      • Binary Tree Tilt
  • Practice
  • Linked Lists
    • What is a Linked List?
    • Add Two Numbers
      • Add Two Numbers 2
    • Reverse a Linked List
    • Tortoise & Hare Algorithm
      • Middle of the Linked List
  • Bitshifting
    • Introduction
  • Not Done Yet
    • Uncompleted
    • Minimum Cost For Tickets
    • Minimum Falling Path Sum
Powered by GitBook
On this page

Was this helpful?

  1. Strings
  2. Two Pointers

Squares of a Sorted Array

PreviousSort Array by ParityNextMax Consecutive Ones

Last updated 4 years ago

Was this helpful?

2 Pointers

The 2 pointers technique is where we have 2 variables pointing at different parts of the array. An example is:

x = [1, 2, 3, 4, 5]
pointer1 = 0
pointer2 = len(x) - 1
while pointer1 <= pointer2:
    print(pointer1 + pointer2)
    pointer1 += 1
    pointer2 -= 1

This code adds the largest element to the smallest element and goes inwards into the code.

Very often we'll want 2, 3, 4 pointers in our array. These pointers do not always have to move at the same speed. Having 2 pointers is often an evolution of using 2 for loops. Look at this problem:

Given an array of sorted numbers and a target sum, find a pair in the array whose sum is equal to the given target.

Given the array is sorted, our first thought might be 2 nested for loops. This is O(n^2). We want O(n).

We can achieve this with pointers.

Place 1 pointer at the start, and and another pointer at the end.

x = [1, 2, 3, 4, 5]
pointer1 = 0
pointer2 = len(x) - 1
target = 7

Now we calculate the sum of the 2 numbers.

1 + 5 = 6
6 < target (7)

We know the value is larger, so we move one to the right.

x = [1, 2, 3, 4, 5]
pointer1 = 2 # value 1
pointer2 = 4 # value 5
sum = 7
sum == target

This algorithm is O(n).

The pointers pattern is an essential pattern for array manipulation, and we will see it come up a lot. Especially with 2 pointers moving at different speeds.

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.

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

There are multiple solutions to this!

Solution 1 - Python with in-built Sort

   def sortedSquares(self, A: List[int]) -> List[int]:
        for i in range(len(A)):
            A[i] *= A[i]
        A.sort()
        return A

Space complexity is O(1) as it is entirely in-place. .sort() is in place. Ask your interviewer what to do here.

Solution 2 - Java with Pointers

We can do this in Java using 2 pointers, which is the way the solution was supposed to be written (it just happens our code is just as fast):

class Solution {
    public int[] sortedSquares(int[] A) {
        int n = A.length;
        int[] result = new int[n];
        int i = 0, j = n - 1;
        for (int p = n - 1; p >= 0; p--) {
            if (Math.abs(A[i]) > Math.abs(A[j])) {
                result[p] = A[i] * A[i];
                i++;
            } else {
                result[p] = A[j] * A[j];
                j--;
            }
        }
        return result;
    }
}

Solution 3 - Python with Pointers

def sortedSquares(self, A):
    answer = collections.deque()
    l, r = 0, len(A) - 1
    while l <= r:
        left, right = abs(A[l]), abs(A[r])
        if left > right:
            answer.appendleft(left * left)
            l += 1
        else:
            answer.appendleft(right * right)
            r -= 1
    return list(answer)

Author explains:

The question boils down to understanding that if we look at the magnitude of the elements in the array, A, both ends "slide down" and converge towards the center of the array. With that understanding, we can use two pointers, one at each end, to iteratively collect the larger square to a list. However, collecting the larger square in a list with list's append, results in elements sorted in descending order. To circumvent this, we need to append to the left of the list. Using a collections.deque() allows us to append elements to the left of answer in O(1) time, maintaining the required increasing order.

This uses built in sort. It should be O(n log n) but due to how Python's sorting algorithm works, it's O(n) amortised. You can learn about why it's O(n) .

This code is from .

From .

https://leetcode.com/explore/learn/card/fun-with-arrays/521/introduction/3240/
here
here
here