java求出最长平台的长度_最长平台的新算法 - 数据结构和算法 - Tech - JavaEye论坛...

最长平台问题描述如下:

一个从小到大排列的数组,这个数组中的一个平台就是连续的一段值相同的元素。例如:122333445中22,333等都是平台,333为最长平台。

一般常见的算法是一个计算机科学家首先给出的。

Java代码 536925_10106182_1.gif

privatestaticintf1(int[] array) {

if(array ==null|| array.length ==0)

return0;

intlength =1;

for(inti =1; i 

if(array[i] == array[i - length])

length++;

}

returnlength;

}

private static int f1(int[] array) {

if (array == null || array.length == 0)

return 0;

int length = 1;

for (int i = 1; i < array.length; i++) {

if (array[i] == array[i - length])

length++;

}

return length;

}

这段代码的确是简洁优雅的,但是在效率上不是很好。

最长平台有一些特点可以利用,从而使得算法的效率更高。

一个分界点元素指该元素和它的前一个元素不相等。

1 从一个分界点开始剩下的元素个数<=length,则可以直接返回。

2 从一个分界点开始找最大平台,没有必要依次顺序查找,直接跳到该(分界点的坐标+length)的元素进行查找。

如果(分界点的坐标+length)也是一个分界点,则从原来的分界点到新的分界点(分界点的坐标+length)之间的 元素可以丢掉,从新的分界点重新开始查找最长平台。

如果(分界点的坐标+length)不是一个分界点,则它有可能在一个最长平台中,判断之,然后继续。

这里主要是考虑到当前最长平台的长度,算法考虑该长度可以跳过一些元素进行处理。

Java代码 536925_10106182_1.gif

/**

* 最长平台更快的算法

*/

privatestaticintf2(int[] array) {

if(array ==null|| array.length ==0)

return0;

// 下一个要检测的位置,保证array[next]!=array[next-1]。

intnext =1;

for(; next 

;

// 第一个平台的长度,next>=1。

intlength = next;

while(next 

// 如果剩下的元素个数<=length,则不可能有最长平台了

if(array.length - next <= length) {

break;

}

// 向前跳跃length+1,到next+length处进行检查,如果array[next+length]!=array[next+length-1],则

// next - (next+length-1)这段数据可以丢弃.

if(array[next + length] != array[next + length -1]) {

next = next + length;

}else{

// 这个相等的值所在的平台的值.

intvalue = array[next + length];

// 这个相等的值所在的平台的最后一个坐标.

intendIndex = next + length +1;

for(; endIndex 

;

endIndex = endIndex -1;

// 向后跳跃length+1,如果相等,则这个平台是最大平台.

if(array[endIndex - length] == value) {

intstartIndex = endIndex - length -1;

for(; array[startIndex] == value; startIndex--)

;

// 更新最大平台的值

length = endIndex - startIndex;

}

next = endIndex +1;

}

}

returnlength;

}

/**

* 最长平台更快的算法

*/

private static int f2(int[] array) {

if (array == null || array.length == 0)

return 0;

// 下一个要检测的位置,保证array[next]!=array[next-1]。

int next = 1;

for (; next < array.length && array[next] == array[0]; next++)

;

// 第一个平台的长度,next>=1。

int length = next;

while (next < array.length) {

// 如果剩下的元素个数<=length,则不可能有最长平台了

if (array.length - next <= length) {

break;

}

// 向前跳跃length+1,到next+length处进行检查,如果array[next+length]!=array[next+length-1],则

// next - (next+length-1)这段数据可以丢弃.

if (array[next + length] != array[next + length - 1]) {

next = next + length;

} else {

// 这个相等的值所在的平台的值.

int value = array[next + length];

// 这个相等的值所在的平台的最后一个坐标.

int endIndex = next + length + 1;

for (; endIndex < array.length && array[endIndex] == value; endIndex++)

;

endIndex = endIndex - 1;

// 向后跳跃length+1,如果相等,则这个平台是最大平台.

if (array[endIndex - length] == value) {

int startIndex = endIndex - length - 1;

for (; array[startIndex] == value; startIndex--)

;

// 更新最大平台的值

length = endIndex - startIndex;

}

next = endIndex + 1;

}

}

return length;

}

code是比上一个复杂一些,但是速度有了很大的提高,大约提高60%以上。

还有改进的余地,如果在查找一个平台的最后一个坐标或者第一个坐标,可以用2分查找

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值