上述做法的贪心思想是:为了找到递增的三元子序列,first 和 second 应该尽可能地小,此时找到递增的三元子序列的可能性更大。
假设 $(\textit{first}, \textit{second}, \textit{num})$ 是一个递增的三元子序列,如果存在 second’ 满足 first} < \textit{second’} < \textit{second 且 second’ 的下标位于 first 的下标和 num 的下标之间,则 $(\textit{first}, \textit{second’}, \textit{num})$ 也是一个递增的三元子序列。但是当 $(\textit{first}, \textit{second’}, \textit{num})$ 是递增的三元子序列时,由于 num 不一定大于 second,因此 $(\textit{first}, \textit{second}, \textit{num})$ 未必是递增的三元子序列。由此可见,为了使找到递增的三元子序列的可能性更大,三元子序列的第二个数应该尽可能地小,将 second’ 作为三元子序列的第二个数优于将 second 作为三元子序列的第二个数。
同理可得,三元子序列的第一个数也应该尽可能地小。
如果遍历过程中遇到的所有元素都大于 first,则当遇到 num} > \textit{second 时,first 一定出现在 second 的前面,second 一定出现在 num 的前面,$(\textit{first}, \textit{second}, \textit{num})$ 即为递增的三元子序列。
如果遍历过程中遇到小于 first 的元素,则会用该元素更新 first,虽然更新后的 first 出现在 second 的后面,但是在 second 的前面一定存在一个元素 first’ 小于 second,因此当遇到 num} > \textit{second 时,$(\textit{first’}, \textit{second}, \textit{num})$ 即为递增的三元子序列。
根据上述分析可知,当遇到 num} > \textit{second 时,一定存在一个递增的三元子序列,该三元子序列的第二个数和第三个数分别是 second 和 num,因此返回 true。
publicclassSolution { publicboolIncreasingTriplet(int[] nums) { int n = nums.Length; if (n < 3) { returnfalse; } int first = nums[0], second = int.MaxValue; for (int i = 1; i < n; i++) { int num = nums[i]; if (num > second) { returntrue; } elseif (num > first) { second = num; } else { first = num; } } returnfalse; } }
classSolution { public: boolincreasingTriplet(vector<int>& nums){ int n = nums.size(); if (n < 3) { returnfalse; } int first = nums[0], second = INT_MAX; for (int i = 1; i < n; i++) { int num = nums[i]; if (num > second) { returntrue; } elseif (num > first) { second = num; } else { first = num; } } returnfalse; } };
[sol2-C]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
boolincreasingTriplet(int* nums, int numsSize){ if (numsSize < 3) { returnfalse; } int first = nums[0], second = INT_MAX; for (int i = 1; i < numsSize; i++) { int num = nums[i]; if (num > second) { returntrue; } elseif (num > first) { second = num; } else { first = num; } } returnfalse; }
[sol2-Golang]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
funcincreasingTriplet(nums []int)bool { n := len(nums) if n < 3 { returnfalse } first, second := nums[0], math.MaxInt32 for i := 1; i < n; i++ { num := nums[i] if num > second { returntrue } elseif num > first { second = num } else { first = num } } returnfalse }
[sol2-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution: defincreasingTriplet(self, nums: List[int]) -> bool: n = len(nums) if n < 3: returnFalse first, second = nums[0], float('inf') for i inrange(1, n): num = nums[i] if num > second: returnTrue if num > first: second = num else: first = num returnFalse
[sol2-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
var increasingTriplet = function(nums) { const n = nums.length; if (n < 3) { returnfalse; } let first = nums[0], second = Number.MAX_VALUE; for (let i = 1; i < n; i++) { const num = nums[i]; if (num > second) { returntrue; } elseif (num > first) { second = num; } else { first = num; } } returnfalse; };