1、题目描述
2、解题思路
本题考的是数学,把输入数组 nums[] 看成横坐标,把输出的数组 ans[] 看成纵坐标。
f(x) = ax² + bx + c
定义一个函数:
public int cal(int x, int a, int b, int c) {
return a * x * x + b * x + c;
}
1、a == 0 且 b == 0
此时 f(x) = c,输出数组 ans[] 的所有值均为 c。
2、a == 0 且 b > 0
此时 f(x) = bx + c,为单调递增函数,把 nums[] 的每个值进行 cal 计算赋值到 ans[] 即可。
3、a == 0 且 b < 0
此时 f(x) = bx + c,为单调递减函数,把 nums[] 的逆序每个值进行 cal 计算顺序赋值到 ans[] 即可。
4、a > 0
此时 f(x) = ax² + bx + c 为开口向上的抛物线,有最小值,最小值横坐标为 mid = -b/2a。
如果我们从 nums[] 中找到距离 mid 最近的,然后当成最小值,赋值给 nums[0],这样操作很繁琐,因为每次都要从 nums[] 找距离 mid 最近的值。我们可以从大到小来赋值。
我们直到,距离 mid 越远的横坐标,它的纵坐标就越大,因此,我们定义两个左右指针为 left = 0, right = nums.length-1,再定义一个 index = nums.legth-1 作为 ans[] 最大值的索引。
1、比较 left - mid 和 rigth - mid 谁的绝对值大,大的那个就是距离 mid 最远的那个;
2、比如 left 距离 mid 最远,则 ans[index] = cal(nums[left],a,b,c),完成最大值赋值;
3、赋值好了最大值,我们调整 left++ 为新的 left,right 不变,index-- 表示找第二大。
循环重复 1 2 3,直到遍历完所有的 nums[] ,此时 ans[] 也赋值完毕。
3、解题代码
class Solution {
public int[] sortTransformedArray(int[] nums, int a, int b, int c) {
// 把 nums[] 看成横坐标,把 ans[] 看成纵坐标
int[] ans = new int[nums.length];
int index;
if (a == 0) { // a==0 是直线
if (b > 0) { // 斜率为正,单调递增
index = 0;
for (int num : nums) {
ans[index++] = cal(num, a, b, c);
}
} else if (b < 0) { // 斜率为负,单调递减
index = nums.length - 1;
for (int num : nums) {
ans[index--] = cal(num, a, b, c);
}
} else { // 水平直线
Arrays.fill(ans, c);
}
} else { // a != 0 是抛物线
double midVal = -b * (1.0 / (2 * a)); // -b/2a 是抛物线的最值
int left = 0;
int right = nums.length - 1;
if (a > 0) { // 开口向上,有最小值
index = nums.length - 1; // 从最大值往下装入 ans 中
while (left <= right) {
// x 距离中心横坐标越远的,y 越大
if (Math.abs(midVal - nums[left]) > Math.abs(midVal - nums[right])) {
ans[index] = cal(nums[left], a, b, c);
left++;
} else {
ans[index] = cal(nums[right], a, b, c);
right--;
}
index--;
}
} else { // 开口向下,有最大值
index = 0;
while (left <= right) {
// x 距离中心横坐标越远的,y 越小
if (Math.abs(midVal - nums[left]) > Math.abs(midVal - nums[right])) {
ans[index] = cal(nums[left], a, b, c);
left++;
} else {
ans[index] = cal(nums[right], a, b, c);
right--;
}
index++;
}
}
}
return ans;
}
public int cal(int x, int a, int b, int c) {
// ax² + bx + c
return a * x * x + b * x + c;
}
}