【数组】Leetcode编程题解:414. Third Maximum Number

题目:Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n).样例:1. Input: [3, 2, 1]Output: 1Explanation: The third maximum is 1.2. Input: [1, 2]Output: 2Explanation: The third maximum does not exist, so the maximum (2) is returned instead.3. Input: [2, 2, 3, 1]Output: 1Explanation: Note that the third maximum here means the third maximum distinct number.Both numbers with value 2 are both considered as second maximum.这道题虽然是easy难度,但是因为之前没有遇到类似的题目,所以只有思路,具体实现方法想了好久。因为题目还要求了时间复杂度,所以采取的方法也有限
本来打算先进行排序,然后挑出第三大数,若不存在,就返回最大数,但是不符合时间复杂度,因而放弃。提交代码:

class Solution {
public:
    int thirdMax(vector<int>& nums) {
        int len = nums.size(), MAX, temp;
        bool num[len];
        memset(num, 0, sizeof(num));
        stack<int> store;
     for(int j = 0; j < 2; j++) {
      for(int i = 0; i < len; i++)
      if(!num[i])
      store.push(nums[i]);
      if(!store.empty()) {
      temp = store.top();
      store.pop();
      while(!store.empty()) {
       if(store.top() > temp) {
        temp = store.top();
        store.pop();
    }
    else
    store.pop();
   }
   for(int i = 0; i < len; i++)
   if(nums[i] == temp)
   num[i] = 1;
   if(j == 0)
   MAX = temp;
  }
      else
      return MAX;
  }
  for(int i = 0; i < len; i++)
  if(!num[i]) {
   for(int i = 0; i < len; i++)
      if(!num[i])
      store.push(nums[i]);
      temp = store.top();
      store.pop();
      while(!store.empty()) {
       if(store.top() > temp) {
        temp = store.top();
        store.pop();
    }
    else
    store.pop();
   }
   return temp;
  }
  return MAX; 
    }
};

虽然通过,但是耗时严重,虽然勉强达到要求。所以在网上找了相关代码,以下是摘抄:

这道题让我们求数组中第三大的数,如果不存在的话那么就返回最大的数,题目中说明了这里的第三大不能和第二大相同,必须是严格的小于,而并非小于等于。这道题并不是很难,如果知道怎么求第二大的数,那么求第三大的数的思路都是一样的。那么我们用三个变量first, second, third来分别保存第一大,第二大,和第三大的数,然后我们遍历数组,如果遍历到的数字大于当前第一大的数first,那么三个变量各自错位赋值,如果当前数字大于second,小于first,那么就更新second和third,如果当前数字大于third,小于second,那就只更新third,注意这里有个坑,就是初始化要用长整型long的最小值,否则当数组中有INT_MIN存在时,程序就不知道该返回INT_MIN还是最大值first了,参见代码如下:

class Solution {
public:
    int thirdMax(vector<int>& nums) {
        long first = LONG_MIN, second = LONG_MIN, third = LONG_MIN;
        for (int num : nums) {
            if (num > first) {
                third = second;
                second = first;
                first = num;
            } else if (num > second && num < first) {
                third = second;
                second = num;
            } else if (num > third && num < second) {
                third = num;
            }
        }
        return (third == LONG_MIN) ? first : third;
    }
};

下面这种方法的时间复杂度是O(nlgn),不符合题目要求,纯粹是拓宽下思路哈,利用了set的自动排序和自动去重复项的特性,很好的解决了问题,对于遍历到的数字,加入set中,重复项就自动去掉了,如果此时set大小大于3个了,那么我们把set的第一个元素去掉,也就是将第四大的数字去掉,那么就可以看出set始终维护的是最大的三个不同的数字,最后遍历结束后,我们看set的大小是否为3,是的话就返回首元素,不是的话就返回尾元素,参见代码如下:

class Solution {
public:
    int thirdMax(vector<int>& nums) {
        set<int> s;
        for (int num : nums) {
            s.insert(num);
            if (s.size() > 3) {
                s.erase(s.begin());
            }
        }
        return s.size() == 3 ? *s.begin() : *s.rbegin();
    }
};

总结:第一次知道可以直接调用某种数据类型的最小值,可以在该题的极端条件下实现寻找最大值(里面有一种情况是使用了int型的最小值),也了解了寻找第几大数的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值