[LeetCode 360] Sort Transformed Array

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+cf(x)=ax​2​​+bx+c to each element xx in the array.

The returned array must be in sorted order.

Example

Example1

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

Example2

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

Notice

Expected time complexity: O(n)

 

分析

这道题最容易想到的解法就是首先计算出所有的结果,然后直接排序,但是复杂度为O(n * logn),不满足题目要求。

这道题如果只是想着找规律很不直观,其实只要画出二次函数的图就能一目了然。

以上图为例,如果a > 0时,二次函数的开口向上,排好序的数组的跨度有三种情况:全在对称轴左边,全在右边,横跨对称轴。但是有一点是不变的,数组的两头所得的结果一定有一个是最大的。利用这个特点,我们使用left,right两个指针分别指向数组首尾,取较大的计算结果,并移动指针。

对于a < 0,二次函数的开口向下,数组两头的结果一定有一个是最小的,利用这个特点,同样使用left, right两个指针分别指向数组首尾,取较小的计算结果,并移动指针。

对于a == 0的情况,一次函数一定是单调的,left,right指针依然适用。

Code

class Solution {
public:
    /**
     * @param nums: a sorted array
     * @param a: 
     * @param b: 
     * @param c: 
     * @return: a sorted array
     */
    vector<int> sortTransformedArray(vector<int> &nums, int a, int b, int c) {
        // Write your code here
        int len = nums.size();
        vector<int> res(len, 0);
        
        int left = 0;
        int right = len -1;
        
        int i = 0;
        while (left <= right)
        {
            int leftRes = a * (nums[left] * nums[left]) + b * nums[left] + c;
            int rightRes = a * (nums[right] * nums[right]) + b * nums[right] + c;
            if (a > 0)
            {
                if (leftRes >= rightRes)
                {
                    res[len - 1 - i] = leftRes;
                    left ++;
                }
                else
                {
                    res[len -1 - i] = rightRes;
                    right --;
                }
            }
            else
            {
                if (leftRes <= rightRes)
                {
                    res[i] = leftRes;
                    left ++;
                }
                else
                {
                    res[i] = rightRes;
                    right --;
                }
            }
            i ++;
        }
        return res;
    }
};

运行效率

Your submission beats 80.67% Submissions!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值