zoukankan      html  css  js  c++  java
  • LeetCode 334 Increasing Triplet

    这个题是说看一个没有排序的数组里面有没有三个递增的子序列,也即:

    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.

    大家都知道这个题有很多解法,然而题主丧心病狂地说要O(n)的时间复杂度和O(1)的空间复杂度。

    我当时考虑的是找三个递增的数,中间那个数比较重要,所以我们可以遍历该数组,检查每个元素是不是递增序列的中间那个数,假设我们叫它为p。

    那要成为p有什么条件呢?召唤画面感。

    p把整个数组划分成两部分。如果在前面有比p小的,且在后面有比p大的,那么成了。反之,(1)如果前面最小的数都比p大,(2)或者后面最大的数都比p小,那么p肯定不是”中间那个数“,对吧?

    那么我们从第二个数开始,检查它是不是p。满足(1),其实可以通过求一个数组最小值来做到,从左到右,如果一个元素是当前最小的,那么肯定就满足(1)了。我们就可以把它从数组里面排除了。同理,从右到左,如果一个元素是当前最大的,那么满足(2)了,排除完了还有剩下的,就是说明有戏了嘛。但是怎么排除呢。。。?人家又不许有临时数组啊。。。O(1)的时间复杂度啊。只有耍机灵了。直接在数组里面吧排除了的数设置成一个invalid number...OMG。玛德智障啊。。。

           bool increasingTriplet(vector<int>& nums)
            {   
    
                vector<int>::iterator it;
                int min = INT_MAX;
                for(it = nums.begin(); it < nums.end(); it++) {
                    if(*it <= min) {
                        min = *it;
                        *it = INT_MIN;//i feel there should not be such element...
                    }
                }
                vector<int>::reverse_iterator rit = nums.rbegin();
                int max = INT_MIN;
                for(; rit < nums.rend(); rit++) {
                   if (*rit >= max && *rit != INT_MIN) {
                       max = *rit;
                   } else if (*rit != INT_MIN){
                       return true;
                   }
                }
                return false;                                                                                                                                                   
            }

    捂脸。。居然过了。

    但是时间就。。。

    于是好奇的猫看了下讨论。天。。好简单的答案。

    if (numsSize < 3) return false;
    int l = nums[0], m = 0x7fffffff;
    for (int i = 1; i < numsSize; i++) {
        int a = nums[i];
        if (a <= l) l = a;
        else if (a < m) m = a;
        else if (a > m) return true;
    }
    return false;

    你萌看懂了伐?

    其实他也认为”中间“那个数是很重要的。所以就是用m来代替。m之前始终有个比他小的数(l,或曾经的l)。所以如果当前遍历到的元素大于了m,那么就return true。

  • 相关阅读:
    C++ 类 构造函数 constructor
    数据库——关系代数
    海明码
    C++ this指针
    C++ 类的定义与实现
    C++ 函数 内联函数
    C++ 函数 函数的重载 有默认参数的函数
    2017年第八届蓝桥杯【C++省赛B组】
    2018年第九届蓝桥杯【C++省赛B组】
    C++ 函数 参数传递方式
  • 原文地址:https://www.cnblogs.com/lichen782/p/5225443.html
Copyright © 2011-2022 走看看