LeetCode 977 题:有序数组的平方
LeetCode 977 题:有序数组的平方 (Squares of a Sorted Array)
LeetCode 第977题要求给定一个按非降序排列的整数数组 nums
,返回每个数字的平方并按升序排列。
题目描述
给定一个整数数组 nums
,它按非降序排列(即 nums[i] <= nums[i+1]
),请返回该数组中每个数字的平方并按升序排列。
示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
解题思路
-
双指针法:
- 因为输入数组已经按非降序排列,所以数组中的元素的平方值并不会有严格的顺序。
- 数组的平方值可能有两个不同的极端值:
- 负数的平方会变大,可能会出现在数组的左侧。
- 正数的平方会变小,可能会出现在数组的右侧。
-
双指针:
- 我们可以使用两个指针,一个从数组的左端开始,另一个从右端开始。比较这两个指针指向的元素的平方值,较大的平方值将放在结果数组的末尾。
- 将结果数组的指针逐渐向中间靠拢,直到所有的平方值都被放入结果数组。
-
复杂度分析:
- 时间复杂度:
O
(
n
)
O(n)
O(n),其中
n
n
n 是数组
nums
的长度。我们只遍历数组一次。 - 空间复杂度: O ( n ) O(n) O(n),我们使用额外的数组存储结果。
- 时间复杂度:
O
(
n
)
O(n)
O(n),其中
n
n
n 是数组
C语言代码实现
以下是使用双指针法的代码实现:
#include <stdio.h>
#include <stdlib.h>
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
int left = 0, right = numsSize - 1;
*returnSize = numsSize;
int* result = (int*)malloc(sizeof(int) * numsSize);
int index = numsSize - 1; // 结果数组的指针从末尾开始
while (left <= right) {
if (abs(nums[left]) > abs(nums[right])) {
result[index--] = nums[left] * nums[left];
left++;
} else {
result[index--] = nums[right] * nums[right];
right--;
}
}
return result;
}
int main() {
int nums[] = {-4, -1, 0, 3, 10};
int returnSize;
int* result = sortedSquares(nums, 5, &returnSize);
printf("Result: ");
for (int i = 0; i < returnSize; i++) {
printf("%d ", result[i]);
}
printf("\n");
free(result); // 释放内存
return 0;
}
逐行解释代码
函数 sortedSquares
int left = 0, right = numsSize - 1;
*returnSize = numsSize;
int* result = (int*)malloc(sizeof(int) * numsSize);
- 初始化左右指针
left
和right
,分别指向数组的起始和末尾。 returnSize
保存结果数组的大小,即numsSize
。- 使用
malloc
动态分配内存给结果数组result
,其大小为输入数组nums
的长度。
int index = numsSize - 1; // 结果数组的指针从末尾开始
index
指针从结果数组的末尾开始,这样可以确保我们从最大值开始填充数组。
while (left <= right) {
if (abs(nums[left]) > abs(nums[right])) {
result[index--] = nums[left] * nums[left];
left++;
} else {
result[index--] = nums[right] * nums[right];
right--;
}
}
- 使用
while
循环,直到left
和right
指针交汇。 - 比较
nums[left]
和nums[right]
的绝对值:- 如果
nums[left]
的绝对值大于nums[right]
,则将nums[left]
的平方放入result
数组的末尾,并将left
指针向右移动。 - 否则,将
nums[right]
的平方放入result
数组的末尾,并将right
指针向左移动。
- 如果
- 每次操作后,
index
指针向前移动,以确保将平方值存入正确的位置。
return result;
- 返回结果数组
result
,它包含按升序排列的平方值。
测试代码 main
int nums[] = {-4, -1, 0, 3, 10};
int returnSize;
int* result = sortedSquares(nums, 5, &returnSize);
printf("Result: ");
for (int i = 0; i < returnSize; i++) {
printf("%d ", result[i]);
}
printf("\n");
free(result); // 释放内存
- 定义一个测试用例
nums = {-4, -1, 0, 3, 10}
。 - 调用
sortedSquares
函数获取结果。 - 打印输出结果数组。
- 使用
free
释放malloc
动态分配的内存。
测试结果
运行代码后输出:
Result: 0 1 9 16 100
复杂度分析
-
时间复杂度: O ( n ) O(n) O(n)
- 我们只遍历一次数组,
left
和right
每次向内移动一次,最终会遍历整个数组。
- 我们只遍历一次数组,
-
空间复杂度: O ( n ) O(n) O(n)
- 我们使用了一个额外的数组
result
来存储平方后的结果。
- 我们使用了一个额外的数组