在下面的Java代码中,是否有任何方法可以加快执行速度?

在下面的Java代码中,是否有任何方法可以加快执行速度?,java,performance,optimization,coding-efficiency,Java,Performance,Optimization,Coding Efficiency,我的Java代码如下所示 boolean almostIncreasingSequence(int[] sequence) { Integer[] arr = new Integer[sequence.length]; for(int ctr = 0; ctr < sequence.length; ctr++) { arr[ctr] = Integer.valueOf(sequence[ctr]); // returns Inte

我的Java代码如下所示

boolean almostIncreasingSequence(int[] sequence) {

        Integer[] arr = new Integer[sequence.length];

        for(int ctr = 0; ctr < sequence.length; ctr++) {
            arr[ctr] = Integer.valueOf(sequence[ctr]); // returns Integer value
        }
        System.out.println("Integer :: " + arr);
        List<Integer> al = new ArrayList<Integer>(); 

        // adding elements of array to arrayList. 
        Collections.addAll(al, arr);
        System.out.println("list :: " + al);
        int save, flag = 0;
        for(int i=0; i<al.size(); i++) {
            save = al.get(i);
            al.remove(i);
            if(al.size()==1) return true;
            for(int j=0; j<al.size()-1; j++) {
                if(al.get(j+1) > al.get(j)) {
                    flag = 0;
                    continue;
                }
                else {
                    flag = 1;
                    break;
                }
            }
                if(flag == 0) {
                    return true;
                }
                al.add(i,save);
            }

        if(flag == 1)
            return false;
        return true;
    }
布尔几乎递增序列(int[]序列){
整数[]arr=新整数[sequence.length];
对于(int-ctr=0;ctr对于(int i=0;i而言,主要观察结果是列表可分解为3个部分(可能为空):

其中
list[0..s)
list[e..length)
是严格递增的列表,而
list[s..e)
是介于两者之间的东西

因为您知道这些前缀和后缀列表是严格递增的,所以不需要在这些列表中重复检查此属性


您可以根据约束选择
s
e
的任何值
0您的代码包含两个嵌套的
for
循环,这两个循环都会遍历整个列表。这意味着,如果您的列表有100000个项目,那么在最坏的情况下,代码将需要100000*100000个步骤。当然,这很慢

由于列表总是“几乎已排序”,您可能不需要检查列表的开头,因为您已经知道它已排序。直观地看,应该足以查看最后几个列表项,并记住列表包含多少未排序的对。

更新2: 也请尝试此代码 (最多2个循环) 进一步优化是可行的,但仍然会产生O(n)时间

我同意这个

编辑:提供更新的解决方案。速度快,但可读性不好。 我还包括了一个main()类,其中包含一些我测试代码时使用的标准序列(使用的格式使测试人员可以轻松地添加任何额外的用例)

/**
*如果通过删除最大1项,序列可以严格增加,则返回true。如果不是,则返回false。不检查
*如果序列为空
*/
私有静态布尔checkIfRemovingMaxOneElementItisStritlyIncremaining(最终int[]序列)
{
布尔值isFirstNonDecreasingSequence=true;
最终整数长度=sequence.length;
int maxValue=序列[0];
for(int i=1;i1)
{

如果(序列[i]=A[i],则确定其在峰值之后(因此A[i-1]为“异常”高且应从序列中移除)还是在凹坑内部(A[i]过低且应从序列中移除).

正确的位置是请让您的编辑器或IDE一致地格式化您的代码。目前它比必要的更难阅读。输入数组和预期结果将帮助我们更好地理解问题。您当前的算法的时间复杂度为
O(N²)
,而此任务在
O(N)中是可行的
。概述了一种算法。你是如何想出这个解决方案的?最有可能的是,最初的海报不只是对有一个解决方案感兴趣,而是对找到它感兴趣,所以这将是很好的解释。@Rolandillg这样的解决方案是创造性思维的结果。当人们说编程是一种艺术形式时,他们的意思是这样的。Ther它没有算法。经验有帮助。@Torben我称之为词汇表或曲目,而不是创造性思维。@AndyTurner“创造性地应用你的词汇表”。:)接近我的解决方案。不过你可以进一步优化:1)如果
a.length在{10,1,2,3,4,5}中失败,则返回true。它应该返回true,但返回false。@Robby,优化后为true。基本上与idea.Thx相同。它在{1,2,5,3,5}中失败。预期为true,但得到了false@Virus,再次为true。进行修复,但不知道是否仍然是最优的,因为{1,2,1,2}预期为false,但变为true。
[10,11,12,1,2,3]
将返回
true
但应该
false
@Talex,你是对的。更新后的提案通过了此测试。病毒,是的,我误读了你说的“严格增加”的“增加”,使用@Virus测试过吗?如果是,你的任务的性能改进如何?
list = list[0..s) + list[s..e) + list[e..length)
public class TstList {

public static boolean compute(int a[]) {
    if (compute_1(a))
        return true;
    return compute_2(a);
}

public static boolean compute_1(int a[]) {
    if (a.length < 2)
        return true;
    int previous = a[0];
    int counter = 0;
    for (int i = 1; i < a.length; i++) {

        if (previous < a[i]) {
            previous = a[i];
            continue;
        } else {
            if (i == 1)
                previous = a[i];
            else
                previous = a[i - 1];

            counter++;
        }

        if (counter > 1)
            return false;
    }
    return true;
}

public static boolean compute_2(int a[]) {
    if (a.length < 2)
        return true;
    int previous = a[0];
    int counter = 0;
    for (int i = 1; i < a.length; i++) {

        if (previous < a[i]) {
            previous = a[i];
            continue;
        } else {
            previous = a[i];
            counter++;
        }

        if (counter > 1)
            return false;
    }
    return true;
}
public static void main(String arg[]) {

    System.out.println(compute(new int[] { 1, 2, 3, 4, 6 }));       \\1
    System.out.println(compute(new int[] { 1, 2, 3, 1, 4, 6 }));    \\2
    System.out.println(compute(new int[] { 1, 2, 1, 3, 1, 4, 6 })); \\3
    System.out.println(compute(new int[] { 1, 2, 3, 4, 6, 3 }));    \\4
    System.out.println(compute(new int[] { 3, 2, 1 }));             \\5
    System.out.println(compute(new int[] { 10, 1, 2, 3, 4, 5 }));   \\6
    System.out.println(compute(new int[] { 1, 2, 5, 3, 5 }));       \\7

}
}
true  \\1
true  \\2
false \\3
true  \\4
false \\5 
true  \\6
true  \\7
/**
 * Returns true if by removing maximum 1-entry the sequence can be strictly increasing.If not, it returns false. Doesn't check
 * if sequence is empty
 */
private static boolean checkIfRemovingMaxOneElementItIsStrictlyIncreasing(final int[] sequence)
{
    boolean isFirstNonDecreasingSequence = true;
    final int length = sequence.length;
    int maxValue = sequence[0];
    for (int i = 1; i < length; i++)
    {
        if (sequence[i] <= maxValue)
        {
            if (isFirstNonDecreasingSequence == true)
            {
                if ((i + 1) < length) // check this is not the last element
                {
                    if ((sequence[i - 1] >= sequence[i + 1])) // Check if it is peak or pit
                    {
                        // [i-1] is a local peak. Remove [i-1]
                        if (i > 1)
                        {
                            if (sequence[i] <= sequence[i - 2])
                            {
                                return false;
                            }
                        }
                        maxValue = sequence[i];
                    }
                    // else { // [i] is a local pit. Remove [i]. maxValue is not updated. }
                    isFirstNonDecreasingSequence = false;
                }
            }
            else
            {
                return false;
            }
        }
        else
        {
            maxValue = sequence[i];
        }
    }
    return true;
}

public static void main(final String[] args)
{
    final List<int[]> testInputs = new ArrayList<>();
    final List<Boolean> correctResults = new ArrayList<>();
    final List<Boolean> results = new ArrayList<>();

    testInputs.add(new int[] { 0 }); // single-element sequence
    correctResults.add(true);

    testInputs.add(new int[] { 0, 0 }); // two-element sequence
    correctResults.add(true);

    testInputs.add(new int[] { 0, 0, 0 }); // constant sequence
    correctResults.add(false);

    testInputs.add(new int[] { 1, 2, 3, 4, 6 }); // strictly increasing
    correctResults.add(true);

    testInputs.add(new int[] { 3, 2, 1 }); // strictly decreasing
    correctResults.add(false);

    testInputs.add(new int[] { 10, 1, 2, 3 }); // first value (10) should be removed
    correctResults.add(true);

    testInputs.add(new int[] { 1, 2, 3, 1 }); // last value (1) should be removed
    correctResults.add(true);

    testInputs.add(new int[] { 1, 2, 5, 3, 5 }); // peak (5) (inner value should be removed)
    correctResults.add(true);

    testInputs.add(new int[] { 1, 2, 3, 10, 4, 4, 5 }); // peak (10) followed by constant (4)
    correctResults.add(false);

    testInputs.add(new int[] { 1, 2, 3, 1, 4, 6 }); // pit (1) (inner value should be removed)
    correctResults.add(true);

    testInputs.add(new int[] { 5, 6, 2, 6, 7 }); // pit (2) that does not recover
    correctResults.add(false);

    testInputs.add(new int[] { 5, 0, 3 }); // first value should be removed
    correctResults.add(true);

    testInputs.add(new int[] { 5, 6, 1, 2 }); // sequence downward gap (pit)
    correctResults.add(false);

    for (int i = 0; i < testInputs.size(); i++)
    {
        results.add(checkIfRemovingMaxOneElementItIsStrictlyIncreasing_NoAssignment(testInputs.get(i)));

        if (correctResults.get(i) == results.get(i))
        {
            System.out.println("Test case: " + i + " successful.");
        }
        else
        {
            System.out.println("Test case: " + i + " should be: " + correctResults.get(i) + " but was: " + results.get(i));
            System.out.println("Test case: " + i + " input array: " + Arrays.toString(testInputs.get(i)));
        }
    }
}
private static boolean checkIfRemovingMaxOneElementItIsStrictlyIncreasing_WithoutAssignment(final int[] sequence)
{
    boolean isFirstNonDecreasingSequence = true;
    final int length = sequence.length;
    for (int i = 1; i < length; i++)
    {
        if (sequence[i] <= sequence[i - 1])
        {
            if (isFirstNonDecreasingSequence == true)
            {
                if ((i + 1) < length) // check this is not the last element
                {
                    if ((sequence[i - 1] >= sequence[i + 1])) // Check if it is peak or pit
                    {
                        // [i-1] is a local peak. Remove [i-1]
                        if (i > 1)
                        {
                            // Check if by removing [i-1] the sequence is actually increasing
                            if (sequence[i] <= sequence[i - 2])
                            {
                                return false;
                            }
                        }
                    }
                    else
                    {
                        // [i] is a local pit. Remove [i]
                        sequence[i] = sequence[i - 1];
                    }
                    isFirstNonDecreasingSequence = false;
                }
            }
            else
            {
                return false;
            }
        }
    }
    return true;
}