Java 如何在时间复杂度方面改进算法?
我试图测量我的算法的时间复杂度:Java 如何在时间复杂度方面改进算法?,java,algorithm,big-o,time-complexity,Java,Algorithm,Big O,Time Complexity,我试图测量我的算法的时间复杂度: public boolean rotateAndCompare(int[] fst, int[] snd) { int len = fst.length; for (int k = 0; k < len; k++) { for (int j = 0; j < len; j++) { if (fst[(k + j) % len] != snd[j]) { break
public boolean rotateAndCompare(int[] fst, int[] snd) {
int len = fst.length;
for (int k = 0; k < len; k++) {
for (int j = 0; j < len; j++) {
if (fst[(k + j) % len] != snd[j]) {
break;
}
if (j == len - 1) {
return true;
}
}
}
return false;
}
public boolean rotateAndCompare(int[]fst,int[]snd){
int len=fst.length;
对于(int k=0;k
我假设它具有O(n*n)
复杂性,因为我们先遍历一个数组,然后遍历另一个数组。我说得对吗?如果是这样的话,我该如何改进呢?O(n*n)通常表示为“n阶平方”,O(n^2),这就是您的算法。然而,由于您绝对不进行长度检查,它可能会完全中断,这比算法复杂性更严重。”snd(这代表什么?为什么这么简洁?)甚至可能没有“len”元素。另外,通过将终端条件作为循环控制的一部分,而不是检查两次,您可以得到一些改进
崩溃的风险远比算法的复杂性严重。一旦你解决了这个问题,你也许可以重构索引使其更线性,但我怀疑这是不可能的。如果您的问题中存在对称性,您可能可以利用它们。如果我理解正确,您的算法将决定
snd
的第一个fst.length
整数是否等于fst
,可能是旋转的。它假定snd.length>=fst.length
。如果这不是你的意思,请在问题中具体说明
但是假设这就是你真正的意思,你可以用一个字符串匹配算法解决这个问题,比如。换句话说,您需要查看是否可以找到snd
作为fst+fst
的子数组,这是一个经典问题
下面是一个Java实现示例:
import java.util.Arrays;
public class Main {
public static class KMP {
private final int F[];
private final int[] needle;
public KMP(int[] needle) {
this.needle = needle;
this.F = new int[needle.length + 1];
F[0] = 0;
F[1] = 0;
int i = 1, j = 0;
while (i < needle.length) {
if (needle[i] == needle[j])
F[++i] = ++j;
else if (j == 0)
F[++i] = 0;
else
j = F[j];
}
}
public int find(int[] haystack) {
int i = 0, j = 0;
int n = haystack.length, m = needle.length;
while (i - j <= n - m) {
while (j < m) {
if (needle[j] == haystack[i]) {
i++;
j++;
} else break;
}
if (j == m) return i;
else if (j == 0) i++;
j = F[j];
}
return -1;
}
}
public static boolean rotateAndCompare(int[] fst, int[] snd) {
int[] fst2 = new int[fst.length * 2];
System.arraycopy(fst, 0, fst2, 0, fst.length);
System.arraycopy(fst, 0, fst2, fst.length, fst.length);
int[] snd2 = Arrays.copyOf(snd, fst.length);
return new KMP(snd2).find(fst2) >= 0;
}
public static void main(String[] args) {
System.out.println(rotateAndCompare(new int[]{1, 2, 3}, new int[]{3, 1, 2, 4}));
System.out.println(rotateAndCompare(new int[]{1, 2, 2}, new int[]{3, 1, 2, 4}));
}
}
导入java.util.array;
公共班机{
公共静态类KMP{
私人最终int F[];
私人终结者[]针;
公共KMP(国际[]针){
这个。针=针;
这个.F=新的整数[指针长度+1];
F[0]=0;
F[1]=0;
int i=1,j=0;
而(i<针长){
if(针[i]==针[j])
F[++i]=++j;
else如果(j==0)
F[++i]=0;
其他的
j=F[j];
}
}
公共int查找(int[]haystack){
int i=0,j=0;
int n=草堆长度,m=针长度;
而(i-j=0;
}
公共静态void main(字符串[]args){
System.out.println(rotateAndCompare(新int[]{1,2,3},新int[]{3,1,2,4}));
System.out.println(rotateAndCompare(新int[]{1,2,2},新int[]{3,1,2,4}));
}
}
我投票结束这个问题,因为关于代码改进的问题属于您,而嵌套循环本身的复杂性是O(n^2),所以我不想讨论这个问题,并且只有当嵌套循环中的任何一个条件在第一次条件检查中得到满足时,这才是近似值。但是,要真正解决您的问题,您需要查看程序的范围以及它的结构。您不能在不知道如何做的情况下问如何改进它。如果您确实需要嵌套循环,那么我们将得到一个指数级增长的复杂性…您是否尝试过:fst={0,0,0,0,0,1}
和snd={0,0,0,0,1,0}
?@DavidPérezCabrera是的,System.out.println(旋转比较(新int[]{0,0,0,1},新int[]{0,1,0}))
=>真的
对不起,我弄错了,你的答案真是太棒了!