Java 如何优化此算法?与chars一起工作
任务:给我们两个长度相同的字符串,m和n。我们想把m修改成n。我们可以执行两个操作 我们可以获取当前字符串的一个连续段,并将该段中的每个字母在字母表中向前移动一次,或在字母表中向后移动一次 我们希望以最少的步骤完成这项工作,目标是一个O(n)算法 这是我的第一次尝试;显然,它甚至还没有达到优化的程度,但我对如何优化它有点迷茫。我不知道如何确定哪段信最好。目前,我的实现一次只完成一个字母Java 如何优化此算法?与chars一起工作,java,Java,任务:给我们两个长度相同的字符串,m和n。我们想把m修改成n。我们可以执行两个操作 我们可以获取当前字符串的一个连续段,并将该段中的每个字母在字母表中向前移动一次,或在字母表中向后移动一次 我们希望以最少的步骤完成这项工作,目标是一个O(n)算法 这是我的第一次尝试;显然,它甚至还没有达到优化的程度,但我对如何优化它有点迷茫。我不知道如何确定哪段信最好。目前,我的实现一次只完成一个字母 public static void shift(String m, String n) { char
public static void shift(String m, String n) {
char mChar[] = m.toCharArray();
char nChar[] = n.toCharArray();
int count = 0;
for (int i = 0; i < m.length(); i++){
while (mChar[i] != nChar[i]){
if (mChar[i] - nChar[i] < 0){
//System.out.println("SHIFT FORWARD");
mChar[i]++;
count++;
}
else{
//System.out.println("SHIFT BACKWARD");
mChar[i]--;
count++;
}
System.out.println(mChar[i]);
}
}
System.out.println(mChar);
System.out.println(count);
}
公共静态无效移位(字符串m、字符串n){
char mChar[]=m.toCharArray();
char nChar[]=n.toCharArray();
整数计数=0;
对于(int i=0;i
这个算法的时间复杂度是多少?For循环使其最小为O(n),而while循环在最坏的情况下可以运行25次(如果我们有“y”并且想要“a”)。我这样想对吗?既然你应该学习如何编程,我就不给你代码,但在这种情况下,我可以帮助你使用正确的算法 我将举例说明:
shift( "AAAAZZZZ", "BCDBZYYX" )
这里的目标是最小化移位操作的数量,因此需要优化正在移位的块大小
首先,确定每个字符所需的移位数:
A A A A Z Z Z Z
B C D B Z Y Y X
+1 +2 +3 +1 0 -1 -1 -2
从第一个位置开始,如果换档为正,则查找正换档的最大连续块。如果为负,则查找负移位块。实行轮班制。重复到零,然后转到下一个字符
1:索引0到3,上移:
B B B B Z Z Z Z
0 +1 +2 0 0 -1 -1 -2
B C C B Z Z Z Z
0 0 +1 0 0 -1 -1 -2
B C D B Z Z Z Z
0 0 0 0 0 -1 -1 -2
2:索引1到2,上移:
B B B B Z Z Z Z
0 +1 +2 0 0 -1 -1 -2
B C C B Z Z Z Z
0 0 +1 0 0 -1 -1 -2
B C D B Z Z Z Z
0 0 0 0 0 -1 -1 -2
3:索引2,上移:
B B B B Z Z Z Z
0 +1 +2 0 0 -1 -1 -2
B C C B Z Z Z Z
0 0 +1 0 0 -1 -1 -2
B C D B Z Z Z Z
0 0 0 0 0 -1 -1 -2
4:索引5到7,下移:
B C D B Z Y Y Y
0 0 0 0 0 0 0 -1
B C D B Z Y Y X
0 0 0 0 0 0 0 0
5:索引7,下移:
B C D B Z Y Y Y
0 0 0 0 0 0 0 -1
B C D B Z Y Y X
0 0 0 0 0 0 0 0
在5班操作中完成
更新
优化:程序不需要提前或根本不需要“确定班次”。这主要是为了帮助说明算法。既然你应该学习如何编程,我就不给你代码了,但在这种情况下,我可以帮助你使用正确的算法 我将举例说明:
shift( "AAAAZZZZ", "BCDBZYYX" )
这里的目标是最小化移位操作的数量,因此需要优化正在移位的块大小
首先,确定每个字符所需的移位数:
A A A A Z Z Z Z
B C D B Z Y Y X
+1 +2 +3 +1 0 -1 -1 -2
从第一个位置开始,如果换档为正,则查找正换档的最大连续块。如果为负,则查找负移位块。实行轮班制。重复到零,然后转到下一个字符
1:索引0到3,上移:
B B B B Z Z Z Z
0 +1 +2 0 0 -1 -1 -2
B C C B Z Z Z Z
0 0 +1 0 0 -1 -1 -2
B C D B Z Z Z Z
0 0 0 0 0 -1 -1 -2
2:索引1到2,上移:
B B B B Z Z Z Z
0 +1 +2 0 0 -1 -1 -2
B C C B Z Z Z Z
0 0 +1 0 0 -1 -1 -2
B C D B Z Z Z Z
0 0 0 0 0 -1 -1 -2
3:索引2,上移:
B B B B Z Z Z Z
0 +1 +2 0 0 -1 -1 -2
B C C B Z Z Z Z
0 0 +1 0 0 -1 -1 -2
B C D B Z Z Z Z
0 0 0 0 0 -1 -1 -2
4:索引5到7,下移:
B C D B Z Y Y Y
0 0 0 0 0 0 0 -1
B C D B Z Y Y X
0 0 0 0 0 0 0 0
5:索引7,下移:
B C D B Z Y Y Y
0 0 0 0 0 0 0 -1
B C D B Z Y Y X
0 0 0 0 0 0 0 0
在5班操作中完成
更新
优化:程序不需要提前或根本不需要“确定班次”。这主要是为了帮助说明算法。尽管@Andreas的答案是可行的,但不是O(N)。当你想知道最坏的情况时,你会在细节上考虑它 如何实施Andreas的回答 您需要知道间隙的大小,这样就不会改变索引的位置,而是块本身。有两个临时变量->
int startIndex,endIndex
首先是startIndex=0,endIndex=-1
,然后当您看到符号更改时,更改endIndex=i
,将块长度i-startIndex
记录在blockSize[]
追加中
然后,当您看到另一个更改时,startIndex=endIndex
,endIndex=i
,将i-startIndex
记录在您的blockSize[]
追加中
当你完成这项工作后,产生答案的代码块如下所示
思考
“我需要增加…最后4个块..让我们看看数组大小可能是N,让我们看看..好的,最后4个是最大的块,现在让我们增加最后4个”
现在为什么那么糟糕?
每次通过递增过程时,都需要通过大小为N的数组,这就是为什么它会导致N^2,明白我的意思吗?对于big Oh,你总是需要考虑字面上最坏的情况,在你的情况下是
[1, -1, 1, -1, 1, -1]
那你怎么办?您将创建一个
[1,1,1,1,1,1]
然后你必须通过这些间隙大小数组N次,找到最大的尺寸,实际上是它们中的任何一个,然后你要通过N次,找到最大的尺寸,通过一个N大小的交替数组,因此N^2
这里有另一种方法,但我不完全确定它是O(N)还是O(N*k),其中k是将一个字母一个字母移位所需的过程中的因子(因为您指定了)
当然,我的方法也有最坏的情况,如下所示:
[1, 4, 12, -3, -2, 3] let's say...
1st. [0,3,11,-4,-3,2]
2nd. [0,0,8,-7,-6,-1]
3rd. [0,0,0,-15,-14,-9]
这将导致总共6次操作,但要增加的索引在过去3年中几乎翻了四倍。我不知道你是直接从a->z,还是a->b->c。。。如果是前者,那么我认为雪崩效应不会很明显
除此之外,我想不出任何O(N)运算,它要求k是常数
当有人回答一个关于大O计算速度的问题时,你应该始终想到这句话:
函数的一种描述,通常只用大O表示法
提供增长的上限