Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[LeetCode] 360. Sort Transformed Array #360

Copy link
Copy link
Open
@grandyang

Description

@grandyang
Issue body actions

Given a sorted array of integers nums and integer values a , b and c. Apply a quadratic function of the form f( x ) = ax 2 + bx + c to each element x in the array.

The returned array must be in sorted order.

Expected time complexity: O( n )

Example 1:

Input: nums = [-4,-2,2,4], a = 1, b = 3, c = 5
Output: [3,9,15,33]

Example 2:

Input: nums = [-4,-2,2,4], a = -1, b = 3, c = 5
Output: [-23,-5,1,7]

Credits:
Special thanks to @elmirap for adding this problem and creating all test cases.

这道题给了一个数组,又给了一个抛物线的三个系数,让求带入抛物线方程后求出的数组成的有序数组。那么首先来看 O(nlgn) 的解法,这个解法没啥可说的,就是每个算出来再排序,这里用了最小堆来帮助我们排序,参见代码如下:

解法一:

class Solution {
public:
    vector<int> sortTransformedArray(vector<int>& nums, int a, int b, int c) {
        vector<int> res;
        priority_queue<int, vector<int>, greater<int>> q;
        for (auto d : nums) {
            q.push(a * d * d + b * d + c);
        }
        while (!q.empty()) {
            res.push_back(q.top()); q.pop();
        }
        return res;
    }
}; 

但是题目中的要求在 O(n) 中实现,那么只能另辟蹊径。其实这道题用到了大量的高中所学的关于抛物线的数学知识,我们知道,对于一个方程 f(x) = ax2 + bx + c 来说,如果 a>0,则抛物线开口朝上,那么两端的值比中间的大,而如果 a<0,则抛物线开口朝下,则两端的值比中间的小。而当 a=0 时,则为直线方法,是单调递增或递减的。那么这里可以利用这个性质来解题,题目中说明了给定数组 nums 是有序的,如果不是有序的,我想很难有 O(n) 的解法。正因为输入数组是有序的,可以根据a来分情况讨论:

当 a>0,说明两端的值比中间的值大,那么此时从结果 res 后往前填数,用两个指针分别指向 nums 数组的开头和结尾,指向的两个数就是抛物线两端的数,将它们之中较大的数先存入 res 的末尾,然后指针向中间移,重复比较过程,直到把 res 都填满。

当 a<0,说明两端的值比中间的小,那么从 res 的前面往后填,用两个指针分别指向 nums 数组的开头和结尾,指向的两个数就是抛物线两端的数,将它们之中较小的数先存入 res 的开头,然后指针向中间移,重复比较过程,直到把 res 都填满。

当 a=0,函数是单调递增或递减的,那么从前往后填和从后往前填都可以,可以将这种情况和 a>0 合并。

解法二:

class Solution {
public:
    vector<int> sortTransformedArray(vector<int>& nums, int a, int b, int c) {
        int n = nums.size(), i = 0, j = n - 1;
        vector<int> res(n);
        int idx = a >= 0 ? n - 1 : 0;
        while (i <= j) {
            if (a >= 0) {
                res[idx--] = cal(nums[i], a, b, c) >= cal(nums[j], a, b, c) ? cal(nums[i++], a, b, c) : cal(nums[j--], a, b, c);
            } else {
                res[idx++] = cal(nums[i], a, b, c) >= cal(nums[j], a, b, c) ? cal(nums[j--], a, b, c) : cal(nums[i++], a, b, c);
            }
        }
        return res;
    }
    int cal(int x, int a, int b, int c) {
        return a * x * x + b * x + c;
    }
}; 

Github 同步地址:

#360

类似题目:

Squares of a Sorted Array

参考资料:

https://leetcode.com/problems/sort-transformed-array/

https://leetcode.com/discuss/108831/java-o-n-incredibly-short-yet-easy-to-understand-ac-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

(欢迎加入博主的知识星球,博主将及时答疑解惑,并分享刷题经验与总结,快快加入吧~)

知识星球 喜欢请点赞,疼爱请打赏❤️~.~

微信打赏

|

Venmo 打赏


---|---

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.