最长平台问题描述如下:
一个从小到大排列的数组,这个数组中的一个平台就是连续的一段值相同的元素。例如:122333445中22,333等都是平台,333为最长平台。
一般常见的算法是一个计算机科学家首先给出的。
这段代码的确是简洁优雅的,但是在效率上不是很好。
最长平台有一些特点可以利用,从而使得算法的效率更高。
一个分界点元素指该元素和它的前一个元素不相等。
1 从一个分界点开始剩下的元素个数<=length,则可以直接返回。
2 从一个分界点开始找最大平台,没有必要依次顺序查找,直接跳到该(分界点的坐标+length)的元素进行查找。
如果(分界点的坐标+length)也是一个分界点,则从原来的分界点到新的分界点(分界点的坐标+length)之间的 元素可以丢掉,从新的分界点重新开始查找最长平台。
如果(分界点的坐标+length)不是一个分界点,则它有可能在一个最长平台中,判断之,然后继续。
这里主要是考虑到当前最长平台的长度,算法考虑该长度可以跳过一些元素进行处理。
code是比上一个复杂一些,但是速度有了很大的提高,大约提高60%以上。
还有改进的余地,如果在查找一个平台的最后一个坐标或者第一个坐标,可以用2分查找。
一个从小到大排列的数组,这个数组中的一个平台就是连续的一段值相同的元素。例如: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分查找。