360. Sort Transformed Array
Given a sorted array of integers nums and integer values a, b 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]
最generic经典的方法就是用radix sort
public int[] SortTransformedArray(int[] nums, int a, int b, int c) { var result = new int[nums.Count()]; for(int i = 0; i< nums.Count() ; i++) { result[i] = a*nums[i]*nums[i] + b * nums[i] + c; } RadixSort(result); return result; } public void RadixSort(int[] data) { int i, j; int[] temp = new int[data.Length]; for (int shift = 31; shift > -1; --shift) { j = 0; for (i = 0; i < data.Length; ++i) { bool move = (data[i] << shift) >= 0; if (shift == 0 ? !move : move) data[i - j] = data[i]; else temp[j++] = data[i]; } Array.Copy(temp, 0, data, data.Length - j, j); } }
另一种利用了二次方程的性质,利用2 pointer。但是要注意a的正负,如果a是负的,最后得到的结果要reverse,因为reverse是O(n)的,也符合要求。或者如果a<0,index从大往小了走。
public int[] SortTransformedArray(int[] nums, int a, int b, int c) { var res = new int[nums.Count()]; double center = -1*(double)b/(2*a); int index =0; int i=0; for(;i< nums.Count();i++) { if(nums[i]>=center) break; } int leftMove = i-1; int rightMove =i; while(index<nums.Count()) { if(leftMove<0) res[index++] = FunctionT(a,b,c,nums[rightMove++]); else if(rightMove>=nums.Count()) res[index++] = FunctionT(a,b,c,nums[leftMove--]); else if(Math.Abs(nums[leftMove] - center) - Math.Abs(nums[rightMove] - center) >0) { res[index++] = FunctionT(a,b,c,nums[rightMove++]); } else { res[index++] = FunctionT(a,b,c,nums[leftMove--]); } } if(a<0) Array.Reverse(res); return res; } public int FunctionT(int a, int b,int c, int x) { return (a*x + b)*x +c; }