Leetcode 1630 Arithmetic Subarrays

题目要求判断等差数列。但是它不是判断某个数组是否是等差数列,而是一个数组的不同子数组是否是等差数列。就像把大象装进冰箱里一样,看到题目就已经有基本的解法了,那就是先根据首尾下标生成子数组,然后判断其是否是等差数列。看了一眼数据规模,最多要判断500次,每次判断最多判断500个数字,想到每次判断时,可能需要排序,耗时看起来不低。然后我就想,有没有其他解法,没想到……。那就先把基础解法写出来试试。

static int x = [] () {ios::sync_with_stdio(false); cin.tie(0); return 0;} ();
class Solution {
 public:
  vector<bool> checkArithmeticSubarrays(vector<int>& nums, vector<int>& l, vector<int>& r) {
    vector<bool> res;
    res.reserve(l.size());

    auto isArithmetic = [&] (const int l, const int r) -> bool {
      vector<int> tmp (nums.begin() + l, nums.begin() + r + 1);
      sort(tmp.begin(), tmp.end());
      const int delta = tmp.back() - tmp.front();
      if (delta == 0) return true;
      const int spaces = tmp.size() - 1;  // 数列中,相邻的两个数之间的“空隙”的数量。
      if (delta % spaces != 0) return false;  // 总共相差的数不能平均的分配到所有的“空隙”中,那么一定不等差
      const int d = tmp[1] - tmp[0];
      for (int i = 1; i < spaces; ++i)
        if (d != tmp[i + 1] - tmp[i]) return false;
      return true;
    };

    for (int i = 0, n = l.size(); i < n; ++i)
      res.emplace_back(isArithmetic(l[i], r[i]));
    return res;
  }
};

通过了,而且一次就通过了,其实惊讶到我了。虽然自我评价中,我是一个细心的人,但是这次提交只是打算用实例来给自己挑错的,结果就通过了。这让我怀疑这道题测试用例是不是没几个。查看结果,有101个测试用例,48毫秒,比88.85%的人快???很难想象比Brute Force还慢是个什么情况。看了看网上大神们的解法,目前还没有高上一个层次的解法,都是剪枝的不同。总感觉这道题还能有其他方法,也许可以借鉴下贪心,动态规划的思想也不一定。今天是大年初五,不熬夜了,近几年血压都是135/90毫米汞柱,比我83岁的奶奶还高,真的要好好休息一段时间了。


#直达链接

LeetCode 1630. Arithmetic Subarrays