[leetcode]Sort Transformed Array
利用了抛物线的性质,中间最小/最大,然后向/从两端逼近。
class Solution: def sortTransformedArray(self, nums: List[int], a: int, b: int, c: int) -> List[int]: result = [] if a == 0: # bx + c if b >= 0: for num in nums: result.append(self.calc(num, a, b, c)) else: for num in nums[::-1]: result.append(self.calc(num, a, b, c)) return result middle = -b / 2 / a minVal = float('inf') idx = -1 for i in range(len(nums)): if abs(nums[i] - middle) < minVal: minVal = abs(nums[i] - middle) idx = i if a > 0: result.append(self.calc(nums[idx], a, b, c)) left = idx - 1 right = idx + 1 while left >= 0 or right < len(nums): if left >= 0 and right < len(nums): leftResult = self.calc(nums[left], a, b, c) rightResult = self.calc(nums[right], a, b, c) if leftResult < rightResult: left -= 1 result.append(leftResult) else: right += 1 result.append(rightResult) elif left >= 0: leftResult = self.calc(nums[left], a, b, c) result.append(leftResult) left -= 1 elif right < len(nums): rightResult = self.calc(nums[right], a, b, c) result.append(rightResult) right += 1 else: # a < 0 left = 0 right = len(nums) - 1 while left < right: if left < idx and right > idx: leftResult = self.calc(nums[left], a, b, c) rightResult = self.calc(nums[right], a, b, c) if leftResult < rightResult: left += 1 result.append(leftResult) else: right -= 1 result.append(rightResult) elif left < idx: leftResult = self.calc(nums[left], a, b, c) result.append(leftResult) left += 1 elif right > idx: rightResult = self.calc(nums[right], a, b, c) result.append(rightResult) right -= 1 result.append(self.calc(nums[idx], a, b, c)) return result def calc(self, x, a, b, c): return a * (x ** 2) + b * x + c