[英]Find the longest increasing subsequence of a list in C
我在嘗試找到構成給定列表的最長增加子序列的元素時遇到問題。
我有算法來查找列表中給定項的值,我理解它使用的方法,我只是不知道要添加什么以及在哪里添加它以便我有組成LIS的數字
這是我現在正在做的事情:
for (A[0] = N[0], i=lis=1; i<n; i++) {
int *l = lower_bound(A, A+lis, N[i]);
lis = max(lis, (l-A)+1);
*l = N[i];
}
A
是存儲部分LIS的數組,但在某些時候它會發生變化,因為可能存在不同的解決方案。 N
是元素數組。
我怎樣才能從這里找到N
最長的后續序列?
您可以使用另外兩個陣列來查找LIS。 例如,如果您的源放在數組A中
1 8 4 12 6 6 1
我們有一個數組B來存儲A的元素,這些元素更可能是LIS的元素。 更確切地說, B將在位置i處作為LIS維護。 加上一個數組idx來記錄位置。
我們從A [0]開始,將A [0]置於B [0]。 由於A [0]附加在B中的位置0,因此idx [0] = 0。
[0] 1 2 3 4 5 6
A | 1 8 4 12 6 6 1
B | (1)
idx | 0
然后對於位置1,由於B中的元素小於A [1],A [1]附加到B.idx [1]記錄B中的位置,即1。
0 [1] 2 3 4 5 6
A | 1 8 4 12 6 6 1
B | 1 (8)
idx | 0 1
對於位置2,與B中的元素相比,A [2]或4更可能是LIS的元素,以便將B維持為LIS。 因此,找到B中最小的元素不小於4並替換,即8。將idx [2]設置為B中替換8的位置。 我想你可以用你的搜索算法來找到這樣一個元素。
0 1 [2] 3 4 5 6
A | 1 8 4 12 6 6 1
B | 1 (4)
idx | 0 1 1
所以繼續這種方式,我們逐步建立idx 。
position 3
0 1 2 [3] 4 5 6
A | 1 8 4 12 6 6 1
B | 1 4 (12)
idx | 0 1 1 2
position 4
0 1 2 3 [4] 5 6
A | 1 8 4 12 6 6 1
B | 1 4 (6)
idx | 0 1 1 2 2
position 5
0 1 2 3 4 [5] 6
A | 1 8 4 12 6 6 1
B | 1 4 (6)
idx | 0 1 1 2 2 2
position 6
0 1 2 3 4 5 [6]
A | 1 8 4 12 6 6 1
B | (1) 4 6
idx | 0 1 1 2 2 2 0
我們有idx記錄位置,現在我們向后掃描idx並找出LIS。
0 1 2 3 4 5 6
A | 1 8 4 12 6 6 1
idx | 0 1 1 2 2 (2) 0 | 6
0 1 2 3 4 5 6
A | 1 8 4 12 6 6 1
idx | 0 1 (1) 2 2 2 0 | 4 6
0 1 2 3 4 5 6
A | 1 8 4 12 6 6 1
idx | (0) 1 1 2 2 2 0 | 1 4 6
因此,輸出LIS是{1,4,6}
代碼和A = {1,8,4,12,6,6,1}作為源
#include <stdio.h>
#include <stdlib.h>
#define INT_INF 10000
int search_replace(int *lis, int left, int right, int key) {
int mid;
for (mid = (left+right)/2; left <= right; mid = (left+right)/2) {
if (lis[mid] > key) {
right = mid - 1;
} else if (lis[mid] == key) {
return mid;
} else if (mid+1 <= right && lis[mid+1] >= key) {
lis[mid+1] = key;
return mid+1;
} else {
left = mid + 1;
}
}
if (mid == left) {
lis[mid] = key;
return mid;
}
lis[mid+1] = key;
return mid+1;
}
int main(void) {
int i, tmp, size = 7, lis_length = -1;
int *answer;
int A[7] = {1,8,4,12,6,6,1},
LIS[7],
index[7] = {0};
LIS[0] = A[0];
for (i = 1; i < size; ++i) {
LIS[i] = INT_INF;
}
for (i = 1; i < size; ++i) {
index[i] = search_replace(LIS, 0, i, A[i]);
if (lis_length < index[i]) {
lis_length = index[i];
}
}
answer = (int*) malloc((lis_length+1) * sizeof(int));
for (i = size-1, tmp = lis_length; i >= 0; --i) {
if (index[i] == tmp) {
answer[tmp] = A[i];
--tmp;
}
}
printf("LIS: ");
for (i = 0; i < lis_length+1; ++i) {
printf("%d ", answer[i]);
}
printf("\n");
return 0;
}
和代碼的輸出
LIS: 1 4 6
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.