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 minimummaximum 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) { //minimummaximum 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 } }