递增的三元子序列的思路探讨与源码
递增的三元子序列的题目如下图,该题属于贪心类和数组类型的题目,主要考察对于搜索方法的使用和数组结构的理解。本文的题目作者想到2种方法,分别是双向遍历方法和二分搜索方法,其中双向遍历方法使用Java进行编写,而二分搜索方法使用Python进行编写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以使用双向遍历方法的思路进行解决,首先计算数组的长度,如果数组的长度小于3,则直接返回False的结果。然后初始化一个整数数组,让新数组的首个元素等于原始数组的首个元素。开始循环遍历原始数组,将原始数组的当前元素和新数组的前一个元素取最小值赋值给新数组的当前元素。再初始化一个整数数组,让新数组的最后一个元素等于原始数组的最后一个元素。从后往前开始循环遍历原始数组,将原始数组的当前元素和新数组的前一个元素取最大值赋值给新数组的当前元素。最后遍历三个数组,当满足条件当前元素大于左边数组的前一个元素并且小于右边数组的后一个元素的时候就返回True的结果,否则最终到遍历结束返回False结果。那么按照这个思路我们的Java代码如下:
#喷火龙与水箭龟
class Solution {
public boolean increasingTriplet(int[] nums) {
int numLen = nums.length;
if (numLen < 3) {
return false;
}
int[] leftMin = new int[numLen];
leftMin[0] = nums[0];
for (int ir = 1; ir < numLen; ir++) {
leftMin[ir] = Math.min(leftMin[ir - 1], nums[ir]);
}
int[] rightMax = new int[numLen];
rightMax[numLen - 1] = nums[numLen - 1];
for (int ir = numLen - 2; ir >= 0; ir--) {
rightMax[ir] = Math.max(rightMax[ir + 1], nums[ir]);
}
for (int ir = 1; ir < numLen - 1; ir++) {
if (nums[ir] > leftMin[ir - 1] && nums[ir] < rightMax[ir + 1]) {
return true;
}
}
return false;
}
}
显然,我们看到双向搜索方法的效果还可以,同时还可以使用二分搜索的方法解决。首先初始化,将最小值赋予两个自定义变量最小值变量和中间值变量,然后开始遍历数组,如果当前元素小于等于最小值,就把当前元素赋值给最小值。否则如果当前元素小于等于中间值,就把当前元素赋值给中间值,否则就直接返回True的结果。如果遍历到结束还没有返回,就直接返回False的结果。所以按照这个思路就可以解决,下面是Python代码:
#喷火龙与水箭龟
class Solution:
def increasingTriplet(self, nums: List[int]) -> bool:
smallNum = inf
middleNum = inf
for ij in nums:
if(ij <= smallNum):
smallNum = ij
elif(ij <= middleNum):
middleNum = ij
else:
return True
return False
从结果来说Java版本的双向搜索方法的效率比较差,而Python版本的二分搜索方法的速度还可以,但应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。