利用了抛物线的性质,中间最小/最大,然后向/从两端逼近。
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