977. Squares Of A Sorted Array
Introduction
The problem of squares of a sorted array is a classic problem in the field of algorithms and data structures. Given a sorted array of integers, the task is to return a new array where each element is the square of the corresponding element in the input array. This problem is a great example of how to use a two-pointer technique to solve a problem efficiently.
Problem Statement
Given a sorted array nums
, return a new array where each element is the square of the corresponding element in the input array. The output array should also be sorted in ascending order.
Example Use Cases
- Input:
nums = [-4, -1, 0, 3, 10]
Output:[0, 1, 9, 16, 100]
- Input:
nums = [-7, -3, 2, 3, 11]
Output:[4, 9, 9, 49, 121]
Solution
The solution to this problem involves using a two-pointer technique to build the output array. The idea is to start from both ends of the input array and compare the squares of the elements at the current positions. The larger square is added to the output array, and the corresponding pointer is moved towards the center of the array.
Here is the C++ code for the solution:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
// Square each element in the input array
for (int i = 0; i < nums.size(); i++) {
nums[i] = nums[i]*nums[i];
}
// Initialize an empty vector to store the output
vector<int> descend;
// Initialize two pointers, one at the beginning and one at the end of the array
int i = 0, j = nums.size()-1;
while (i <= j) {
// Compare the squares of the elements at the current positions
if (nums[i] < nums[j]) {
// Add the larger square to the output array and move the right pointer
descend.emplace_back(nums[j]);
j--;
} else if (nums[i] > nums[j]) {
// Add the larger square to the output array and move the left pointer
descend.emplace_back(nums[i]);
i++;
} else {
// Add the square to the output array and move both pointers
descend.emplace_back(nums[i]);
i++;
}
}
// Initialize an empty vector to store the final output
vector<int> ans;
while (descend.size()) {
// Add the elements from the output array to the final output array
ans.emplace_back(descend.back());
descend.pop_back();
}
// Return the final output array
return ans;
}
};
Explanation
The solution works as follows:
- First, we square each element in the input array using a simple loop.
- Then, we initialize an empty vector
descend
to store the output array. - We initialize two pointers,
i
andj
, to the beginning and end of the array,. - We use a while loop to compare the squares of the elements at the current positions of the two pointers.
- If the square of the element at the right pointer is larger, we add it to the output array and move the right pointer.
- If the square of the element at the left pointer is larger, we add it to the output array and move the left pointer.
- If the squares are equal, we add the square to the output array and move both pointers.
- Finally, we add the elements from the output array to the final output array and return it.
Time Complexity
The time complexity of the solution is O(n), where n is the size of the input array. This is because we are using a single loop to compare the squares of the elements at the current positions of the two pointers.
Space Complexity
The space complexity of the solution is O(n), where n is the size of the input array. This is because we are using a vector to store the output array.
Conclusion
Q: What is the problem of squares of a sorted array?
A: The problem of squares of a sorted array is a classic problem in the field of algorithms and data structures. Given a sorted array of integers, the task is to return a new array where each element is the square of the corresponding element in the input array. The output array should also be sorted in ascending order.
Q: What is the input and output format of the problem?
A: The input is a sorted array of integers, and the output is a new array where each element is the square of the corresponding element in the input array. The output array should also be sorted in ascending order.
Q: What is the time complexity of the solution?
A: The time complexity of the solution is O(n), where n is the size of the input array. This is because we are using a single loop to compare the squares of the elements at the current positions of the two pointers.
Q: What is the space complexity of the solution?
A: The space complexity of the solution is O(n), where n is the size of the input array. This is because we are using a vector to store the output array.
Q: How does the two-pointer technique work in this solution?
A: The two-pointer technique works by initializing two pointers, one at the beginning and one at the end of the array. We then compare the squares of the elements at the current positions of the two pointers. If the square of the element at the right pointer is larger, we add it to the output array and move the right pointer. If the square of the element at the left pointer is larger, we add it to the output array and move the left pointer. If the squares are equal, we add the square to the output array and move both pointers.
Q: What are the advantages of using the two-pointer technique in this solution?
A: The two-pointer technique has several advantages in this solution. It allows us to compare the squares of the elements at the current positions of the two pointers in a single loop, which reduces the time complexity of the solution. It also allows us to use a single vector to store the output array, which reduces the space complexity of the solution.
Q: What are the common pitfalls to avoid when using the two-pointer technique?
A: There are several common pitfalls to avoid when using the two-pointer technique. One of the most common pitfalls is to forget to move the pointers correctly. Another common pitfall is to use the wrong pointer to compare the elements. To avoid these pitfalls, it is essential to carefully read and understand the problem statement and the solution.
Q: How can I optimize the solution for large input arrays?
A: To optimize the solution for large input arrays, you can use a more efficient algorithm or data structure. For example, you can use a binary search algorithm to find the square root of the elements in the input array. You can also use a more efficient data structure, such as a heap or a balanced binary search tree, to store the output array.
Q What are the real-world applications of the two-pointer technique?
A: The two-pointer technique has several real-world applications. It is commonly used in algorithms and data structures to solve problems that involve comparing elements in an array or a linked list. It is also used in computer graphics and game development to perform tasks such as collision detection and object sorting.
Q: How can I practice and improve my skills in using the two-pointer technique?
A: To practice and improve your skills in using the two-pointer technique, you can try solving problems that involve comparing elements in an array or a linked list. You can also try implementing the two-pointer technique in different programming languages and data structures. Additionally, you can try to optimize the solution for large input arrays and real-world applications.