力扣-300 最长递增子序列
面试碰到了,除了需要找到最长递增字符串之外,还要输出同长度中字典序最小的。
func lengthOfLIS(nums []int) int {
stack := []int{}
var ans []int
for _, v := range nums{
if len(stack) == 0 || stack[len(stack) - 1] < v{
stack = append(stack, v)
ans = make([]int, len(stack))
copy(ans, stack)
} else if stack[len(stack) - 1] > v{
ind := bisearch(v, stack)
stack[ind] = v
for i := 0; i < len(stack); i++{
if ans[i] > stack[i]{
copy(ans, stack)
break
}
}
}
}
fmt.Println(ans)
return len(stack)
}
func bisearch(a int, b []int) int{
left, right := 0, len(b)
for left < right{
mid := (left + right) / 2
if b[mid] == a{
return mid
} else if b[mid] < a{
left = mid + 1
}else{
right = mid
}
}
return left
}
核心思路是维护一个单调增的栈,遍历切片,如果当前元素大于单调栈栈顶元素,则追加到末尾,否则通过二分找到他在栈中可以替换的位置,即第一个大于等于他的数。
为了找到最小字典序递增序列,选择在追加时copy一份栈,在修改栈内值时,进行遍历比较。
此处踩坑copy函数
定义:func copy(dst, src []Type) int
坑:切片dst需要先初始化长度,否则如果dst容量小于src,将只会copy dst容量的元素,有遗漏。
浙公网安备 33010602011771号