func lengthOfLISSlow(nums []int) int { n := len(nums) if n <= 1 { return n } lis := make([]int, n) // DP, O(n^2) time complexity lis[0] = 1 for i := 1; i < n; i *= 2 { copy(lis[i:], lis[:i]) } max := 1 for i := 1; i < n; i++ { for j := 0; j < i; j++ { if nums[j] < nums[i] && lis[i] < lis[j]+1 { lis[i] = lis[j] + 1 if max < lis[i] { max = lis[i] } } } } return max } func lengthOfLIS(nums []int) int { n := len(nums) if n <= 1 { return n } lis := []int{nums[0]} max := 1 for i := 1; i < n; i++ { if lis[max-1] < nums[i] { lis = append(lis, nums[i]) // O(nlog(n)), maintain the smallest LIS only max++ } else { beg, end := 0, max for beg < end { mid := beg + (end-beg)/2 if lis[mid] < nums[i] { beg = mid + 1 } else if nums[i] < lis[mid] { end = mid } else { beg = mid break } } lis[beg] = nums[i] } } return max }