力扣-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容量的元素,有遗漏。

  参照

posted @ 2022-11-15 21:17  学个习  阅读(7)  评论(0)    收藏  举报