【Leetcode】360. Sort Transformed Array

题目地址:

https://leetcode.com/problems/sort-transformed-array/

给定一个二次整系数多项式 f f f,再给定一个整数数组 A A A,已经按升序排好序,要求返回数组 f ( A ) f(A) f(A)并且也按升序排序,并且要求 O ( n ) O(n) O(n)时间复杂度。

由初中数学知识知道,当抛物线开口向上时,最大值在区间端点取到,而若开口向下时,最小值在区间端点取到。所以可以用对撞双指针,如果开口向上,则把最大、次大等等存入最终结果,返回前反个序即可;若开口向下,则把最小、次小等等存入最终结果,直接返回。注意到题目没说 a a a一定是 0 0 0,但如果 a a a 0 0 0的话,抛物线退化为直线,等同于开口向下的做法,所以代码里只需注意将其归结为 a < 0 a<0 a<0的情况去做即可。代码如下:

public class Solution {
    public int[] sortTransformedArray(int[] nums, int a, int b, int c) {
        if (nums == null || nums.length == 0) {
            return nums;
        }
        
        int[] res = new int[nums.length];
        int idx = 0;
        
        int i = 0, j = nums.length - 1;
        while (i <= j) {
            int f1 = f(nums[i], a, b, c), f2 = f(nums[j], a, b, c);
            // 开口向上,按从大到小的顺序存入res
            if (a > 0) {
                if (f1 >= f2) {
                    res[idx++] = f1;
                    i++;
                } else {
                    res[idx++] = f2;
                    j--;
                }
            } else {
            	// 否则若开口向下或者退化为直线,则按从小到大的顺序存入res
                if (f1 <= f2) {
                    res[idx++] = f1;
                    i++;
                } else {
                    res[idx++] = f2;
                    j--;
                }
            }
        }
        // 如果开口向上还需要给数组反个序
        if (a > 0) {
            reverse(res);
        }
        
        return res;
    }
    
    private void reverse(int[] nums) {
        int i = 0, j = nums.length - 1;
        while (i < j) {
            int tmp = nums[i];
            nums[i] = nums[j];
            nums[j] = tmp;
            i++;
            j--;
        }
    }
    
    private int f(int x, int a, int b, int c) {
        return a * x * x + b * x + c;
    }
}

时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值