[LeetCode] 360. Sort Transformed Array 排序转换后的数组

Given a sorted array of integers nums and integer values ab and c. Apply a 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:

nums = [-4, -2, 2, 4], a = 1, b = 3, c = 5,

Result: [3, 9, 15, 33]

nums = [-4, -2, 2, 4], a = -1, b = 3, c = 5

Result: [-23, -5, 1, 7]

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

解法1:把每一个数带入方程计算结果,然后对结果排序。Time: O(nlogn),不是题目想要的

解法2:根据抛物线方程式的特点,a>0则抛物线开口朝上,两端的值比中间的大,a<0则抛物线开口朝下,则两端的值比中间的小,a=0时,则为直线方法,是单调递增或递减的。同时因为给定数组nums是有序的,所以才有O(n)的解法。

当a>0,两端的值比中间的大,从后边往中间填数,用两个指针分别指向数组的开头和结尾,比较两个数,将其中较大的数存入res,然后该指针向中间移,重复比较过程,直到把res都填满。

当a<0,两端的值比中间的小,从前边往中间填数,用两个指针分别指向数组的开头和结尾,比较两个数,将其中较小的数存入res,然后该指针向中间移,重复比较过程,直到把res都填满。

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

Java:

public class Solution {    
    private int calcu(int x, int a, int b, int c){
        return a*x*x + b*x + c;
    }
    
    
    public int[] sortTransformedArray(int[] nums, int a, int b, int c) {
        int index;
        if(a > 0){
            index = nums.length - 1 ;
        } else {
            index = 0;
        }
        int result[] = new int[nums.length];
        int i = 0;
        int j = nums.length - 1;
        if(a > 0){
            while(i <= j){
                result[index--] = calcu(nums[i],a,b,c) > calcu(nums[j],a,b,c) ? calcu(nums[i++],a,b,c):calcu(nums[j--],a,b,c);
            }
        }else{
            while(i <= j){
                result[index++] = calcu(nums[i],a,b,c) < calcu(nums[j],a,b,c) ? calcu(nums[i++],a,b,c):calcu(nums[j--],a,b,c);
            }  
        }
        return result;
    }
}  

Python: wo

class Solution():
    def sortTransformedArray(self, nums, a, b, c):
        if not nums:
            return []
        res = [0] * len(nums)
        i, j = 0, len(nums) - 1
        index = len(nums) - 1 if a >= 0 else 0
        while i <= j:
            if a >= 0:
                calc_i = self.calc(nums[i], a, b, c)
                calc_j = self.calc(nums[j], a, b, c)
                if  calc_i >= calc_j:
                    res[index] = calc_i
                    i += 1
                else:
                    res[index] = calc_j
                    j -= 1
                index -= 1
            else:
                calc_i = self.calc(nums[i], a, b, c)
                calc_j = self.calc(nums[j], a, b, c)
                if  calc_i <= calc_j:
                    res[index] = calc_i
                    i += 1
                else:
                    res[index] = calc_j
                    j -= 1
                index += 1

        return res

    def calc(self, x, a, b, c):
        return  a * x * x + b * x + c


if __name__ == '__main__':
    print Solution().sortTransformedArray([], 1, 3, 5)
    print Solution().sortTransformedArray([2], 1, 3, 5)
    print Solution().sortTransformedArray([-4, -2, 2, 4], 1, 3, 5)
    print Solution().sortTransformedArray([-4, -2, 2, 4], -1, 3, 5)
    print Solution().sortTransformedArray([-4, -2, 2, 4], 0, 3, 5)

C++:

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;
    }
}; 

C++:

class Solution {
public:
    vector<int> sortTransformedArray(vector<int>& nums, int a, int b, int c) {
        if(nums.size() ==0) return {};
        vector<int> result;
        int left = 0, right = nums.size()-1;
        auto func = [=](int x) { return a*x*x + b*x + c; };
        while(left <= right)
        {
            int val1 = func(nums[left]), val2 = func(nums[right]);
            if(a > 0) result.push_back(val1>=val2?val1:val2);
            if(a > 0) val1>val2?left++:right--;
            if(a <= 0) result.push_back(val1>=val2?val2:val1);
            if(a <= 0) val1>val2?right--:left++;
        }
        if(a > 0) reverse(result.begin(), result.end());
        return result;
    }
};

  

  

 

All LeetCode Questions List 题目汇总

posted @ 2018-09-29 13:42  轻风舞动  阅读(580)  评论(0编辑  收藏  举报