用二分法寻找最长连续单调递增子序列
2006-03-16 17:23
489 查看
/* 在由n个数组成的序列中,找出最长的单调递增子序列。子序列是连续的 */
#include <iostream>
using namespace std;
template <typename T>
void ArrCopy ( const T arrSource[],
const int& startPosition,
T *& arrDestination,
const int& count )
{ // 从数组arrSource的第startPosition开始,复制count个元素到数组arrDestination
if(arrDestination)
{
delete [] arrDestination;
arrDestination = 0;
}
arrDestination = new T[count];
int pos = 0;
for ( int i = startPosition; i < startPosition+count; ++i )
{
arrDestination[pos++] = arrSource[i];
}
}
template <typename T>
void PrintArr ( const T arr[],
const int& size )
{ // 输出数组元素
for( int i = 0; i < size; ++i )
{
cout << arr[i] << " ";
}
cout << endl;
}
template <typename T>
void GetMaxIncSubArr( const T arr[], // 源序列
const int& size, // 源序列的长度
T *& sub, // 生成的子序列
int& subSize ) // 子序列的长度
{
if ( size <= subSize )
{
return;
}
// 确定tempSubSize的值
int tempSubSize = 1;
int pointer = size >> 1; // pointer指向源序列的中部
while( pointer + 1 < size &&
arr[pointer+1] > arr[pointer] )
{ // 若pointer右边的数大于pointer所指向的数,pointer右移,tempSubSize自增
++tempSubSize;
++pointer;
}
pointer = size >> 1; // 指示器重新指向源序列的中部
while( pointer > 0 &&
arr[pointer-1] < arr[pointer] )
{ // 若pointer左边的数小于pointer所指向的数,pointer左移,tempSubSize自增
++tempSubSize;
--pointer;
}
// pointer现在指向了位于源序列中部的单调递增子序列的首元素
if ( tempSubSize > subSize )
{ // 如果这个子序列比以往找到的子序列都要长,更新subSize
subSize = tempSubSize;
ArrCopy<T>(arr, pointer, sub, subSize);
}
int * left = 0; // left是位于源序列中部的单调递增子序列的左边部分
int leftSize = pointer;
if ( leftSize > subSize )
{
ArrCopy<T>(arr, 0, left, leftSize);
}
int * right = 0; // right是位于源序列中部的单调递增子序列的右边部分
int rightSize = size - pointer - subSize;
if ( rightSize > subSize )
{
ArrCopy<T>(arr, pointer+subSize, right, rightSize);
}
if ( pointer > subSize )
{ // 对左边部分计算最长的单调递增子序列
GetMaxIncSubArr(left, leftSize, sub, subSize);
delete [] left;
}
if(rightSize > subSize)
{ // 对右边部分计算最长的单调递增子序列
GetMaxIncSubArr(right, rightSize, sub, subSize);
delete [] right;
}
}
int main(int argc, char* argv[])
{
int arr[] = {0,1,2,3,4,5,6,7,8,9};
int size = sizeof(arr)/sizeof(int);
int* sub = 0;
int subSize = 0;
GetMaxIncSubArr<int>(arr, size, sub, subSize);
cout << subSize << endl;
PrintArr<int>(sub, subSize);
delete [] sub;
cin.get();
return 0;
}
#include <iostream>
using namespace std;
template <typename T>
void ArrCopy ( const T arrSource[],
const int& startPosition,
T *& arrDestination,
const int& count )
{ // 从数组arrSource的第startPosition开始,复制count个元素到数组arrDestination
if(arrDestination)
{
delete [] arrDestination;
arrDestination = 0;
}
arrDestination = new T[count];
int pos = 0;
for ( int i = startPosition; i < startPosition+count; ++i )
{
arrDestination[pos++] = arrSource[i];
}
}
template <typename T>
void PrintArr ( const T arr[],
const int& size )
{ // 输出数组元素
for( int i = 0; i < size; ++i )
{
cout << arr[i] << " ";
}
cout << endl;
}
template <typename T>
void GetMaxIncSubArr( const T arr[], // 源序列
const int& size, // 源序列的长度
T *& sub, // 生成的子序列
int& subSize ) // 子序列的长度
{
if ( size <= subSize )
{
return;
}
// 确定tempSubSize的值
int tempSubSize = 1;
int pointer = size >> 1; // pointer指向源序列的中部
while( pointer + 1 < size &&
arr[pointer+1] > arr[pointer] )
{ // 若pointer右边的数大于pointer所指向的数,pointer右移,tempSubSize自增
++tempSubSize;
++pointer;
}
pointer = size >> 1; // 指示器重新指向源序列的中部
while( pointer > 0 &&
arr[pointer-1] < arr[pointer] )
{ // 若pointer左边的数小于pointer所指向的数,pointer左移,tempSubSize自增
++tempSubSize;
--pointer;
}
// pointer现在指向了位于源序列中部的单调递增子序列的首元素
if ( tempSubSize > subSize )
{ // 如果这个子序列比以往找到的子序列都要长,更新subSize
subSize = tempSubSize;
ArrCopy<T>(arr, pointer, sub, subSize);
}
int * left = 0; // left是位于源序列中部的单调递增子序列的左边部分
int leftSize = pointer;
if ( leftSize > subSize )
{
ArrCopy<T>(arr, 0, left, leftSize);
}
int * right = 0; // right是位于源序列中部的单调递增子序列的右边部分
int rightSize = size - pointer - subSize;
if ( rightSize > subSize )
{
ArrCopy<T>(arr, pointer+subSize, right, rightSize);
}
if ( pointer > subSize )
{ // 对左边部分计算最长的单调递增子序列
GetMaxIncSubArr(left, leftSize, sub, subSize);
delete [] left;
}
if(rightSize > subSize)
{ // 对右边部分计算最长的单调递增子序列
GetMaxIncSubArr(right, rightSize, sub, subSize);
delete [] right;
}
}
int main(int argc, char* argv[])
{
int arr[] = {0,1,2,3,4,5,6,7,8,9};
int size = sizeof(arr)/sizeof(int);
int* sub = 0;
int subSize = 0;
GetMaxIncSubArr<int>(arr, size, sub, subSize);
cout << subSize << endl;
PrintArr<int>(sub, subSize);
delete [] sub;
cin.get();
return 0;
}
相关文章推荐
- 最长单调"连续"递增子序列
- (p226)最长单调递增子序列
- 5-1 最长连续递增子序列
- 最长连续递增子序列
- POJ1631最长单调递增子序列
- hdu 4604 Deque (二分法求最长单调子序列)
- 时间复杂度为O(nlogn)的最长单调递增子序列
- 求数组中最长连续递增子序列
- 最长公共子序列LCS和最长单调递增子序列
- 矩阵中最长连续递增子序列
- 最长连续递增子序列
- 最长连续递增子序列
- 设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。
- 最长连续递增子序列
- 天梯赛2 重现5-4 最长连续递增子序列
- NYOJ 17 最长单调递增子序列
- 【EPI-6.6】最长连续递增子序列-启发式搜索
- 最长连续递增子序列
- 线段树区间合并+最长连续递增子序列——HDU 3308
- 最长递增子串(LIS)算法_严格单调递增_单调递增_连续_不连续