我正在为比赛做准备,但是当我使用O(n)时,我的程序速度总是非常慢。首先,我甚至不知道如何制作O(log n),或者我从未听说过这种范式。我在哪里可以了解到这一点?
例如,
如果你有一个带有0和1的整数数组,例如[0,0,0,1,0,1],现在你只想在其中一个邻居之后用0 替换每个0 / strong>的值为1,如果必须多次出现,最有效的方法是什么? (该程序必须执行此操作数t次)
编辑: 这是我效率低下的解决方案:
import java.util.Scanner;
public class Main {
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
int n;
long t;
n = input.nextInt();
t = input.nextLong();
input.nextLine();
int[] units = new int[n + 2];
String inputted = input.nextLine();
input.close();
for(int i = 1; i <= n; i++) {
units[i] = Integer.parseInt((""+inputted.charAt(i - 1)));
}
int[] original;
for(int j = 0; j <= t -1; j++) {
units[0] = units[n];
units[n + 1] = units[1];
original = units.clone();
for(int i = 1; i <= n; i++) {
if(((original[i - 1] == 0) && (original[i + 1] == 1)) || ((original[i - 1] == 1) && (original[i + 1] == 0))) {
units[i] = 1;
} else {
units[i] = 0;
}
}
}
for(int i = 1; i <= n; i++) {
System.out.print(units[i]);
}
}
}
答案 0 :(得分:2)
这是一个基本的细胞自动机。这种动态系统具有可用于您的优势的属性。例如,在您的情况下,您可以将距离任何初始值1(光锥属性)的距离最多为t的每个单元格设置为值1。然后你可以做类似的事情:
然后你可以在下一步中把你的位置pt设置为p + t ...这可以让你计算最后一步t而无需计算中间步骤(加速的好因素不是吗?)。
您也可以使用一些技巧作为HashLife,请参阅1。
答案 1 :(得分:1)
正如我在评论中所说,我相当确定你可以阻止阵列和clone
操作。
您可以就地修改StringBuilder
,因此无需在int[]
和String
之间来回转换。
例如,(注意:这是所有O(n)
的{{1}}操作的顺序
T <= N
对于您在评论中发布的问题中的两个示例,此代码生成此输出。
public static void main(String[] args) {
System.out.println(conway1d("0000001", 7, 1));
System.out.println(conway1d("01011", 5, 3));
}
private static String conway1d(CharSequence input, int N, long T) {
System.out.println("Generation 0: " + input);
StringBuilder sb = new StringBuilder(input); // Will update this for all generations
StringBuilder copy = new StringBuilder(); // store a copy to reference current generation
for (int gen = 1; gen <= T; gen++) {
// Copy over next generation string
copy.setLength(0);
copy.append(input);
for (int i = 0; i < N; i++) {
conwayUpdate(sb, copy, i, N);
}
input = sb.toString(); // next generation string
System.out.printf("Generation %d: %s\n", gen, input);
}
return input.toString();
}
private static void conwayUpdate(StringBuilder nextGen, final StringBuilder currentGen, int charPos, int N) {
int prev = (N + (charPos - 1)) % N;
int next = (charPos + 1) % N;
// **Exactly one** adjacent '1'
boolean adjacent = currentGen.charAt(prev) == '1' ^ currentGen.charAt(next) == '1';
nextGen.setCharAt(charPos, adjacent ? '1' : '0'); // set cell as alive or dead
}
答案 2 :(得分:0)
BigO表示法是一种简化算法的复杂性。基本上,两个算法O(n)可以具有非常不同的执行时间。为什么?让我们展开你的例子:
所以,实质上你的算法是 O(k * t * n)。如果 t 处于 n 的相同数量级,则可以将复杂度视为 O(k * n ^ 2)。< / p>
优化此算法有两种方法: