配列の中の最長の増分のサブシーケンスを求めます
3253 ワード
ここでは、解法2のコードを示します.
/* * Copyright (c) 2011 alexingcool. All Rights Reserved. */#include #include #include #define DEBUG #undef DEBUG using namespace std; #define INF 65535 int array[] = {1, -1, 2, -3, 4, -5, 6, -7}; const int size = sizeof array/sizeof *array; int MaxIncrSeq(int (&array)[size]) { int minLast[size + 1]; int record[size]; int maxLen = 1; for(int i = 0; i < size; i++) { record[i] = 1; } minLast[1] = array[0]; for(int i = 1; i < size; i++) { int j; for(j = maxLen; j >= 1; j--) { if(array[i] > minLast[j]) { record[i] = j + 1; break; } } if(record[i] > maxLen) { maxLen = record[i]; cout << array[i] << ": "<< maxLen << endl; minLast[maxLen] = array[i]; } if(minLast[j + 1] > array[i]) minLast[j + 1] = array[i]; } return maxLen; } void main() { int maxLen = MaxIncrSeq(array); cout << "max incresing len: "<< maxLen << endl; }
本書の解法3の改良に従って,二分検索を行い,複雑度をO(nlogn)に低減することができる.
/* * Copyright (c) 2011 alexingcool. All Rights Reserved. */#include #include #include #define DEBUG #undef DEBUG using namespace std; #define INF 65535 int array[] = {1, -1, 2, -3, 4, -5, 6, -7, -6, -5, -4, -3, -2}; const int size = sizeof array/sizeof *array; int BinarySearch(int *array, int size, int data) { int left = 1, right = size; if(data > array[right]) { return right; } if(data < array[left]) { return left - 1; } while(left < right) { int mid = left + (right - left)/2; if(mid == left) return mid; if(data > array[mid]) left = mid; else right = mid; } } int MaxIncrSeq(int (&array)[size]) { int minLast[size + 1]; int record[size]; int maxLen = 1; bool flag = false; for(int i = 0; i < size; i++) { record[i] = 1; } minLast[1] = array[0]; for(int i = 1; i < size; i++) { int j = BinarySearch(minLast, maxLen, array[i]); record[i] = j + 1; if(record[i] > maxLen) { maxLen = record[i]; minLast[maxLen] = array[i]; } if(minLast[j + 1] > array[i]) minLast[j + 1] = array[i]; } return maxLen; } void main() { int maxLen = MaxIncrSeq(array); cout << "max incresing len: "<< maxLen << endl; }
/* * Copyright (c) 2011 alexingcool. All Rights Reserved. */#include
本書の解法3の改良に従って,二分検索を行い,複雑度をO(nlogn)に低減することができる.
/* * Copyright (c) 2011 alexingcool. All Rights Reserved. */#include
/*
* Copyright (c) 2011 alexingcool. All Rights Reserved.
*/
#include <iostream>
#include <iterator>
#include <algorithm>
#define DEBUG
#undef DEBUG
using namespace std;
#define INF 65535
int array[] = {3, 2, 1, 2, 3};
const int size = sizeof array / sizeof *array;
int findLongestIncrement(int *array, int size)
{
if (array == NULL || size <= 0)
return -1;
int *minValue = new int[size + 1];
int maxLen = 1;
minValue[1] = *array;
for (int i = 1; i < size; i++)
{
int j;
for (j = maxLen; j >= 1; j--)
{
if (array[i] < minValue[j])
;
else
break;
}
if (j == maxLen)
{
maxLen = j + 1;
minValue[j + 1] = array[i];
}
else
{
if (minValue[j + 1] > array[i])
minValue[j + 1] = array[i];
}
}
delete[] minValue;
return maxLen;
}
void main()
{
int ret = findLongestIncrement(array, size);
cout << "ret = " << ret << endl;
}