360. Sort Transformed Array

package LeetCode_360

/**
 * 360. Sort Transformed Array
 * (Prime)
 * 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]
 * */
class Solution {
    /*
    * solution 1: minHeap, put into head after calculate, Time complexity:O(nlogn), Space complexity:O(n);
    * solution 2: math, parabola, which has minimum\maximum in the middle if a!=0; or is a line if a==0;
    * 1. 当a>0,说明两端的值比中间的值大,那么此时我们从结果res后往前填数,用两个指针分别指向nums数组的开头和结尾,指向的两个数就是抛物线两端的数,
    * 将它们之中较大的数先存入res的末尾,然后指针向中间移,重复比较过程,直到把res都填满。
      2. 当a<0,说明两端的值比中间的小,那么我们从res的前面往后填,用两个指针分别指向nums数组的开头和结尾,指向的两个数就是抛物线两端的数,
      将它们之中较小的数先存入res的开头,然后指针向中间移,重复比较过程,直到把res都填满。
      3. 当a=0,函数是单调递增或递减的,那么从前往后填和从后往前填都可以,我们可以将这种情况和a>0合并。
    * */
    fun sortTransformedArray(nums: IntArray, a: Int, b: Int, c: Int): IntArray {
        //solution 2
        val len = nums.size
        val result = IntArray(len)
        var left = 0
        var right = len-1
        var pos1 = 0
        var pos2 = len-1
        while (left <= right) {
            val first = calculate(nums[left], a, b, c)
            val second = calculate(nums[right], a, b, c)
            if (a >= 0) {
                //minimum\maximum in the middle
                //put the large one in the end of result and move the pointer
                if (first > second) {
                    result[pos2--] = first
                    left++
                } else {
                    result[pos2--] = second
                    right--
                }
            } else {
                //is a line, the element in head or end is less then middle,
                //put the small one in first and move the pointer
                if (first < second) {
                    result[pos1++] = first
                    left++
                } else {
                    result[pos1++] = second
                    right--
                }
            }
        }
        return result
    }

    private fun calculate(x: Int, a: Int, b: Int, c: Int): Int {
        return a * x * x + b * x + c
    }
}

 

posted @ 2020-10-03 16:23  johnny_zhao  阅读(113)  评论(0编辑  收藏  举报