
题目描述
给你一个已经 排好序 的整数数组 nums 和整数 a 、 b 、 c 。对于数组中的每一个元素 nums[i] ,计算函数值 f(x) = ax2 + bx + c ,请 按升序返回数组 。
示例 1:
输入: nums = [-4,-2,2,4], a = 1, b = 3, c = 5
输出: [3,9,15,33]
示例 2:
输入: nums = [-4,-2,2,4], a = -1, b = 3, c = 5
输出: [-23,-5,1,7]
提示:
1 <= nums.length <= 200
-100 <= nums[i], a, b, c <= 100
nums 按照 升序排列
进阶:你可以在时间复杂度为 O(n) 的情况下解决这个问题吗?
解法
方法一:数学 + 双指针
根据数学知识可知,二次函数的图像是一条抛物线,当 \(a \gt 0\) 时,抛物线开口向上,顶点为最小值;当 \(a \lt 0\) 时,抛物线开口向下,顶点为最大值。
由于数组 \(\textit{nums}\) 已经排好序,我们可以使用双指针分别指向数组的两端,根据 \(a\) 的正负决定从结果数组的头部还是尾部开始填充较大(或较小)的值。
时间复杂度 \(O(n)\),空间复杂度 \(O(n)\)。其中 \(n\) 是数组 \(\textit{nums}\) 的长度。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 | class Solution:
def sortTransformedArray(
self, nums: List[int], a: int, b: int, c: int
) -> List[int]:
def f(x: int) -> int:
return a * x * x + b * x + c
n = len(nums)
i, j = 0, n - 1
ans = [0] * n
for k in range(n):
y1, y2 = f(nums[i]), f(nums[j])
if a > 0:
if y1 > y2:
ans[n - k - 1] = y1
i += 1
else:
ans[n - k - 1] = y2
j -= 1
else:
if y1 > y2:
ans[k] = y2
j -= 1
else:
ans[k] = y1
i += 1
return ans
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 | class Solution {
public int[] sortTransformedArray(int[] nums, int a, int b, int c) {
int n = nums.length;
int[] ans = new int[n];
int i = 0, j = n - 1;
IntUnaryOperator f = x -> a * x * x + b * x + c;
for (int k = 0; k < n; k++) {
int y1 = f.applyAsInt(nums[i]);
int y2 = f.applyAsInt(nums[j]);
if (a > 0) {
if (y1 > y2) {
ans[n - k - 1] = y1;
i++;
} else {
ans[n - k - 1] = y2;
j--;
}
} else {
if (y1 > y2) {
ans[k] = y2;
j--;
} else {
ans[k] = y1;
i++;
}
}
}
return ans;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 | class Solution {
public:
vector<int> sortTransformedArray(vector<int>& nums, int a, int b, int c) {
int n = nums.size();
vector<int> ans(n);
int i = 0, j = n - 1;
auto f = [&](int x) {
return a * x * x + b * x + c;
};
for (int k = 0; k < n; k++) {
int y1 = f(nums[i]);
int y2 = f(nums[j]);
if (a > 0) {
if (y1 > y2) {
ans[n - k - 1] = y1;
i++;
} else {
ans[n - k - 1] = y2;
j--;
}
} else {
if (y1 > y2) {
ans[k] = y2;
j--;
} else {
ans[k] = y1;
i++;
}
}
}
return ans;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | func sortTransformedArray(nums []int, a int, b int, c int) []int {
f := func(x int) int {
return a*x*x + b*x + c
}
n := len(nums)
ans := make([]int, n)
i, j := 0, n-1
for k := 0; k < n; k++ {
y1, y2 := f(nums[i]), f(nums[j])
if a > 0 {
if y1 > y2 {
ans[n-k-1] = y1
i++
} else {
ans[n-k-1] = y2
j--
}
} else {
if y1 > y2 {
ans[k] = y2
j--
} else {
ans[k] = y1
i++
}
}
}
return ans
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 | function sortTransformedArray(nums: number[], a: number, b: number, c: number): number[] {
const f = (x: number): number => a * x * x + b * x + c;
const n = nums.length;
let [i, j] = [0, n - 1];
const ans: number[] = Array(n);
for (let k = 0; k < n; ++k) {
const y1 = f(nums[i]);
const y2 = f(nums[j]);
if (a > 0) {
if (y1 > y2) {
ans[n - k - 1] = y1;
++i;
} else {
ans[n - k - 1] = y2;
--j;
}
} else {
if (y1 > y2) {
ans[k] = y2;
--j;
} else {
ans[k] = y1;
++i;
}
}
}
return ans;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 | /**
* @param {number[]} nums
* @param {number} a
* @param {number} b
* @param {number} c
* @return {number[]}
*/
var sortTransformedArray = function (nums, a, b, c) {
const f = x => a * x * x + b * x + c;
const n = nums.length;
let [i, j] = [0, n - 1];
const ans = Array(n);
for (let k = 0; k < n; ++k) {
const y1 = f(nums[i]);
const y2 = f(nums[j]);
if (a > 0) {
if (y1 > y2) {
ans[n - k - 1] = y1;
++i;
} else {
ans[n - k - 1] = y2;
--j;
}
} else {
if (y1 > y2) {
ans[k] = y2;
--j;
} else {
ans[k] = y1;
++i;
}
}
}
return ans;
};
|