[LeetCode] Sort Transformed Array 變換數組排序


 

Given a sorted array of integers nums and integer values aband c. Apply a quadratic function of the form f(x) = ax2 + 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;
    }
}; 

 

類似題目:

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 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM