给一个数组,求它的最大的波峰波谷的落差。
举例:数组 A={2, 3, 6, 5, 7, 9}, 其中 6 和 9 被看做是波峰,2和5则是波谷。D[2, 6]=4, D[6,5]=1, D=[5,9]=4. 则 Thus, MaxD(A)=4.
想法:波峰不一定是数组中的最大值,他是趋势向下的转折点,波谷也不一定是数组中的最小值,他是趋势向上的转折点。数组中最边上的两个元素比较特殊,他们必然属于转折的部分。如果A[0] < A[1] 则A[0]是波谷,反之则是波峰。
先扫描一次数组,找到其中所有的转折点,然后配对计算出他们的差,取差最大的。
测试数据:
2 3 6 5 7 9
2 3 6 5 7
2 3 6 5 7 9 10
示例程序:
#include <iostream> using namespace std; void scanPeak(int arr[], int length, int* pvlst) { int i = 0; int curr_peak = 0; int curr_val = 0; bool is_continue = true; for (i = 1; i < length-1; i++) { if ((arr[i] < arr[i-1]) && (arr[i] < arr[i+1])) { pvlst[i] = -1; } else if ((arr[i] > arr[i-1]) && (arr[i] > arr[i+1])) { pvlst[i] = 1; } } if (arr[0] < arr[1]) pvlst[0] = -1; else if (arr[0] > arr[1]) pvlst[0] = 1; if (arr[length-1] < arr[length-2]) pvlst[length-1] = -1; else if (arr[length-1] > arr[length-2]) pvlst[length-1] = 1; } void maxNeighboringPeak(int arr[], int length) { int i = 0; int * pvlst = NULL; int peak = 0; int vall = 0; int pair = 0; int max = 0; pvlst = new int[length]; memset(pvlst, 0, sizeof(int)*length); scanPeak(arr, length, pvlst); for (i = 0; i < length; i++) { cout << pvlst[i] << " "; } cout << endl << endl; for (i = 0; i < length; i++) { if (pvlst[i] == 1) { peak = i; pair++; } if (pvlst[i] == -1) { vall = i; pair++; } if (2 == pair) { pair = 0; if (arr[peak]-arr[vall] > max) max = arr[peak]-arr[vall]; } } cout << max << endl; delete[] pvlst; pvlst = NULL; } int main() { //int arr[6] = {2, 3, 6, 5, 7, 9}; //int arr[5] = {2, 3, 6, 5, 7}; int arr[7] = {2, 3, 6, 5, 7, 9, 10}; int length = sizeof(arr)/sizeof(arr[0]); maxNeighboringPeak(arr, length); cout<<endl; cin >> length; return 0; }
-1 0 1 -1 0 0 1
5