題目
LIS(Longest Increasing Subsequence)最長上升(不下降)子序列
解決方法:
方法一:
public int lengthOfLIS(int[] nums) {
int[] dp = new int[nums.length];
int len = 0;
for (int num : nums) {
int i = Arrays.binarySearch(dp, 0, len, num);
if (i < 0) {
i = -(i + 1);
}
dp[i] = num;
if (i == len) {
len++;
}
}
return len;
}
補充:
//binarySearch 方法 如果找到 返回正數 如果數字正好在第0個位置 那麼就返回0 //
// 否則返回負數
//如果返回負數,負數的值爲 -(1+理論上存在的index)
//比如下面的例子 3應該出現的位置 在第三個 所以返回-(1 + 2)
int[] ints = {1,2,4};
System.out.println(Arrays.binarySearch(ints, 0, ints.length, 3));
//這個直接返回0
System.out.println(Arrays.binarySearch(ints, 0, ints.length, 1));
方法二:
public int longestIncreceSubsquence2(int[] nums){
int piles = 0, n = nums.length;
int[] top = new int[n];
for (int i = 0; i < n; i++) {
// 要處理的撲克牌
int poker = nums[i];
int left = 0, right = piles;
// 二分查找插入位置
while (left < right) {
int mid = (left + right) / 2;
if (top[mid] == poker){
left = mid;
break;
}
if (top[mid] >= poker)
right = mid;
else
left = mid + 1;
}
if (left == piles) piles++;
// 把這張牌放到牌堆頂
top[left] = poker;
}
// 牌堆數就是 LIS 長度
return piles;
}
方法三:
public int longestIncreceSubsquence(int[] arr){
int temp[] = new int[arr.length];
int size = 0,left =0,mid,right;
for (int i : arr) {
//對於每一個數字 查找插入位置
left = 0;
right = size;
while (left < right){
//查找位置
mid = (left + right) / 2;
//如果找到了 沒有什麼問題
//如果沒有找到 那麼對於左右兩邊的兩個數來說
//left + right /2 結果一定等於left 的值
if (temp[mid] == i){
left = mid;
break;
}else if (temp[mid] > i) {
//我們找的就是第一個比自己大的值 所有右邊要包含當前值
right = mid;
}else {
left = mid + 1;
}
}
if (left > size) {
size ++;
}
if (left == size) {
if (i > temp[left]) {
size++;
if (left + 1 < temp.length) {
left ++;
}
}
}
//如果比所有的數都大
temp[left] = i;
}
return size;
}