package main import "fmt" func lengthOfLIS(nums []int) int { if len(nums) == 0 { return 0 } dp := make([]int, len(nums)) for i := range dp { dp[i] = 1 } for i := 1; i < len(nums); i++ { for j := 0; j < i; j++ { if nums[i] > nums[j] && dp[i] < dp[j]+1 { dp[i] = dp[j] + 1 } } } maxLen := 0 for _, v := range dp { if v > maxLen { maxLen = v } } return maxLen } func main() { arr := []int{10, 9, 2, 5, 3, 7, 101, 18} fmt.Println(lengthOfLIS(arr)) }
The code uses dynamic programming to find the length of the longest increasing subsequence. The longest increasing subsequence in the array [10, 9, 2, 5, 3, 7, 101, 18] is of length 4, for example: [2, 3, 7, 101].
After computing the LIS length, we often backtrack from the last element of the LIS to the first. Using a stack helps reverse the order so the subsequence is output in correct order.
package main import ( "fmt" "sort" ) func lengthOfLIS(nums []int) int { tails := []int{} for _, num := range nums { i := sort.Search(len(tails), func(i int) bool { return tails[i] >= num }) if i == len(tails) { tails = append(tails, num) } else { tails[i] = num } } return len(tails) } func main() { arr := []int{0, 8, 4, 12, 2, 10, 6, 14, 1, 9} fmt.Println(lengthOfLIS(arr)) }
This code uses a binary search approach to maintain a tails array where each element is the smallest possible tail of an increasing subsequence of a given length. The length of tails at the end is the LIS length. For the input, the LIS length is 4.
package main import "fmt" func lengthOfLIS(nums []int) int { dp := make([]int, len(nums)) for i := 0; i < len(nums); i++ { dp[i] = 1 } for i := 1; i < len(nums); i++ { for j := 0; j < i; j++ { if nums[i] > nums[j] && dp[i] < dp[j]+1 { dp[i] = dp[j] + 1 } } } maxLen := 0 for _, v := range dp { if v > maxLen { maxLen = v } } return maxLen } func main() { arr := []int{3, 4, 1, 2} fmt.Println(lengthOfLIS(arr)) }
The loop initializing dp uses i <= len(nums), which tries to access dp[len(nums)] causing an index out of range runtime error.
package main import "fmt" func lengthOfLIS(nums []int) int { dp := make([]int, len(nums)) for i := range dp { dp[i] = 1 } for i := 1; i < len(nums); i++ { for j := 0; j < i; j++ { if nums[i] > nums[j] && dp[i] < dp[j]+1 { dp[i] = dp[j] + 1 } } } maxLen := 0 for _, v := range dp { if v > maxLen { maxLen = v } } return maxLen } func main() { arr := []int{5, 1, 6, 2, 3, 4} lisLen := lengthOfLIS(arr) fmt.Println(len(arr) - lisLen) }
The longest increasing subsequence length is 4 ([1, 2, 3, 4]). So minimum removals = 6 - 4 = 2.
