在下面的Java代码中,是否有任何方法可以加快执行速度?
我的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
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;
}