最长平台的新算法

最长平台问题描述如下:

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

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

	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)不是一个分界点,则它有可能在一个最长平台中,判断之,然后继续。
这里主要是考虑到当前最长平台的长度,算法考虑该长度可以跳过一些元素进行处理。


	/**
* 最长平台更快的算法
*/
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分查找。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值