前言
写这篇文章的主要目的是为了熟悉一下MarkDown这个编辑方式。因为昨天有道云笔记发布对MarkDown的支持,后知后觉的我才发现了这个编辑器,因此打算写一篇小算法来练练手。这个算法也不算难,虽然我也参考了别人的代码。
LeetCode 334
题目
Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array.
Formally the function should:Return true if there exists i, j, k
such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return false.Your algorithm should run in O(n) time complexity and O(1) space complexity.
Examples:
Given [1, 2, 3, 4, 5],
return true.
Given [5, 4, 3, 2, 1],
return false.
题目大意
即判断一个数组中是否至少有三个上升序列
题解
此题可设置两个变量来保存状态。
- min 保存三个数中最小的数
- mid 保存三个数中处于中间的数字
初始时,将最小值min设为数组中的第一个数字,第二大的数值mid设为整数最大值Integer.MAX_VALUE。然后遍历数组,若遇到的数字大于mid,则说明存在min < mid < max,因此返回true;若遇到的数字大于min且小于mid,则将mid修改为此数字;若遇到的数字小于min,则将min修改为此数字。如此即可判断是否存在三个递增的数字。
代码如下
public class Solution {
public boolean increasingTriplet(int[] nums) {
if (nums.length < 3)
return false;
int min = nums[0];
int mid = Integer.MAX_VALUE;
for (int i = 1; i < nums.length; ++i) {
if (nums[i] < min) {
min = nums[i];
}
else if (nums[i] > mid)
return true;
else if (nums[i] > min && nums[i] < mid){
mid = nums[i];
}
}
return false;
}
}
总结
- 这个算法的设计非常巧妙,由该算法产生的mid前一定存在一个数小于mid,因此即使现在min变成其它更小的数了,但只要找到一个数大于mid,就能证明有三个上升排序的数字。同理,当找到一个数字大于min而小于mid时,将mid更新为此数字,即降低mid的大小,因为mid前有一个比它更小的数字,所以在后续的查找中,只要找到比mid大的数字即可返回true。
- 写完这篇博客,感觉这个编辑器太好用了,非常方便,也不怎么需要调整格式。