递增的三元子序列——贪心

135 阅读1分钟

image.png

代码 1 双向遍历:

  1. 如题:找到一个元素,其左有一个小于自己的元素,其右有一个大于自己的元素
  2. 每次遍历满足一个条件,第一次正向遍历,找到当前元素的左边的最小值
  3. 第二层反向遍历,找到当前元素右边的最大值
  4. 最后找到左《 自己 《 右 的元素
  5. 如果没有最后返回false
func increasingTriplet(nums []int) bool {
    n := len(nums)
    if n < 3 {
        return false
    }
    leftMin := make([]int, n)
    leftMin[0] = nums[0]
    for i := 1; i < n; i++ {
        leftMin[i] = min(leftMin[i-1], nums[i])
    }
    rightMax := make([]int, n)
    rightMax[n-1] = nums[n-1]
    for i := n - 2; i >= 0; i-- {
        rightMax[i] = max(rightMax[i+1], nums[i])
    }
    for i := 1; i < n-1; i++ {
        if nums[i] > leftMin[i-1] && nums[i] < rightMax[i+1] {
            return true
        }
    }
    return false
}

func min(a, b int) int {
    if a > b {
        return b
    }
    return a
}

func max(a, b int) int {
    if b > a {
        return b
    }
    return a
}

代码 2 贪心:

  1. 赋初始值,且满足 a < b,开始找第三个数
  2. 第三个数有三种情况
  3. 其一,如果大于 b ,则三数满足条件,返回true
  4. 其二,如果小于 b, 且大于 a ,则将值赋给 b, 更新 b 值
  5. 其三,如果小于 a, 则更新 a 值,
  6. 虽然在第三种情况下,我们将 a 的下标更新到了,b 下标的后面,无需担心,因为我们知道,b 前面有一个小于自己的值,也就是老版本的 a ,所以不影响计算
func increasingTriplet(nums []int) bool {
    n := len(nums)
    if n < 3 {
        return false
    }
    first, second := nums[0], math.MaxInt32
    for i := 1; i < n; i++ {
        num := nums[i]
        if num > second {
            return true
        } else if num > first {
            second = num
        } else {
            first = num
        }
    }
    return false
}