Longest incremental subsequence (LIS) dynamic programming, greedy + dichotomy (java version)

Posted by Jeremy_North on Tue, 08 Feb 2022 12:19:44 +0100

catalogue

Problem Description:

Dynamic programming: (n^2)

java code:

Greed + dichotomy: (nlongn)

java code:

Use of binarysearch():

Problem Description:

Given a sequence, such as arr=[10, 9, 2, 5, 3, 7, 101, 18], find the longest increasing subsequence of the sequence.

The longest increasing subsequence (LIS) can be solved by dynamic programming with n^2 complexity or greedy plus dichotomy with nlongn complexity.

Dynamic programming: (n^2)

Let dp[i] be the maximum length at the end of arr[i], then at the beginning, the element values in dp array are all 1 (self length). Take the above array as an example:

dp[0] = 1(10)

dp[1] = 1(9)

dp[2] = 1(2)

dp[3] = dp[2] + 1 = 2(2,5)

dp[4] = dp[2] + 1 = 2(2,3)

dp[5] = dp[2] + 1 = 2 or dp[5] = dp[3] + 1 = 3 or dp[5] = dp[4] + 1 = 3 (2,7) (2,5,7) (2,3,7)

dp[6] = dp[0... 5] + 1, DP [i] < DP [6], whichever is the largest

The maximum value stored in dp is the final maximum length.

java code:

public class Main {
	public static void main(String[] args) {
		int []arr = new int[] {10, 9, 2, 5, 3, 7, 101, 18};
		int []dp = new int[arr.length];
		
		for(int i = 0; i < arr.length; i++) {//Traversing elements in arr
			dp[i] = 1;//The dp array is initialized to 1, that is, its length is 1
			for(int j = 0; j < i; j++) {//Element before traversing dp[i]
				if(arr[j] < arr[i]) {//Less than current element
					dp[i] = Math.max(dp[i], dp[j] + 1);//compare
				}
			}
		}
		int max = Integer.MIN_VALUE;//Find the maximum value stored in dp
		for(int i = 0; i < arr.length; i++) {
			max = Math.max(max, dp[i]);
		}
		System.out.println(max);
	}
}

Greed + dichotomy: (nlongn)

For a rising subsequence, the smaller the element of the end value, the more conducive it is to add new elements after it, making the length the longest.

Taking arr=[10, 9, 2, 5, 3, 7, 101, 18] as an example, let the element values in the dp array be the longest sequence. The following is the dynamic change process of dp:

① dp[0] = 10. If there is no element, add 10 directly

② dp[0] = 9, because 9 is smaller than 10, and the length is still 1 after changing to 9, and it is more likely to butt the following elements

③ dp[0] = 2, because 2 is smaller than 9, and the length is still 1 after changing to 2, and it is more likely to connect with the following elements. For example, when 5 comes later, 2 can be directly followed by 5, while 9 cannot (greedy thinking, local optimization)

④ dp[1] = 5, adding 5 can make the length longer

⑤ dp[1] = 3, you should find the element that is just less than 3, and then overwrite the following element with 3 (you can use two points when searching)

⑥ dp[2] = 7 (ditto below)

⑦dp[3] = 101

⑧dp[3] = 18

java code:

import java.util.Arrays;

public class Main {
	public static void main(String[] args) {
		int []arr = new int[] {10, 9, 2, 5, 3, 7, 101, 18};
		int []dp = new int[arr.length];
		
		int len = 0;//The rightmost end of binary search (card range), the number of "meaningful" elements in dp
		for(int i = 0; i < arr.length; i++) {
			int index = Arrays.binarySearch(dp, 0, len, arr[i]);
			if(index < 0) {
				index = -(index + 1);//Change index to expected position
			}
			dp[index] = arr[i];//Update or append
			if(index == len) {
				len++;
			}
		}
		System.out.println(len);
	}
}

Use of binarysearch():

binnarySearch() of the tool class Arrays is called during binary search. When using this method to find the element to be found, the found index is returned; If it cannot be found, a negative number is returned. Assuming that the non-existent elements should be located at index r when sorting, then - (r + 1) is the returned negative value.

For example:

public class BinarySeach {
	public static void main(String[] args) {
		int[] src = { 1, 2, 4, 5, 7, 8, 12 };
		System.out.print(Arrays.binarySearch(src, 10)); //-7
	}
}

If 10 does not exist in the src array, a negative number is returned. When 10 is placed in the ordered array src, it should be at index 6, so the negative value returned is - (6 + 1), that is, - 7.

Topics: Java Dynamic Programming greedy algorithm