1. 程式人生 > >LeetCode 334. Increasing Triplet Subsequence

LeetCode 334. Increasing Triplet Subsequence

前言

寫這篇文章的主要目的是為了熟悉一下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。
  • 寫完這篇部落格,感覺這個編輯器太好用了,非常方便,也不怎麼需要調整格式。