使用二分的思路来源于一种叫做patience game
的纸牌游戏。
public class 二分解决最长上升子序列 {
public static void main(String[] args) {
int[] num = {1, 4, 5, 2, 3, 8, 6, 7, 9};
System.out.println(search(num));
}
static int search(int[] nums) {
int[] top = new int[nums.length];
int pok;//当前要解决的牌
int cnt = 0;//当前的牌堆数
for (int i = 0; i < nums.length; i++) {
pok = nums[i];
//找到小于等于当前牌的最左端的牌堆
int left = 0, right = cnt;
//搜索所有堆顶的牌,找到一个适合放下当前牌的位置,即小于等于当前牌的第一个位置。
while (left < right) {
int mid = (left + right) / 2;
if (top[mid] == pok) {
right = mid;
} else if (top[mid] < pok) {
left = mid + 1;
} else if (top[mid] > pok) {
right = mid;
}
}
//没找到合适的牌堆放下,新建一个堆
if (left == cnt) cnt++;
//把这张牌放到牌顶
top[cnt] = pok;
}
//堆数就是最长上升子序列的长度
return cnt;
}
}