算术切片 II - C++ 中的子序列

c++server side programmingprogramming更新于 2024/8/31 5:46:00

假设我们有一个数组 A,其中有 N 个数字。该数组的子序列切片是任何整数序列,如 (K0, K1, K2, … Kn),其中 0 <= K0 < K1 < K2 < … < Kn < N。如果序列 A[K0], A[K1], … 满足以下条件,则 A 的子序列切片 (K0, K1, K2, … Kn) 称为算术切片: A[Kn] 是算术的,所以这意味着 n >= 2。所以我们必须返回算术切片的数量。

因此,如果输入是 [2,4,6,8,10],那么答案将是 7,因为有 7 个算术切片。 [2,4,6], [2,4,10], [4,6,8], [6,8,10], [2,4,6,8], [4,6,8,10], [2,4,6,8,10],

为了解决这个问题,我们将遵循以下步骤 −

  • ret := 0
  • 定义一个映射 dp 另一个映射 cnt
  • 通过从 A 中获取元素来定义一个集合 s
  • n := A 的大小
  • 初始化 i := 1,当 i < n,更新(将 i 增加 1),执行 −
    • 初始化 j := i - 1,当 j >= 0 时,更新(将 j 减少 1),执行 −
      • diff := A[i] - A[j]
      • 如果 diff <= -inf 或 diff > inf,则执行 −
        • 忽略以下部分,跳至下一次迭代
      • temp := dp[j, diff],当 diff 在映射 dp[j] 中时,否则为 0
      • ret := ret + temp
      • 如果 (A[i] + diff) 存在于 s 中,则 −
        • dp[i, diff] := dp[i, diff] + temp + 1
  • return ret

让我们看看下面的实现以便更好地理解 −

示例

#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
class Solution {
public:
   int numberOfArithmeticSlices(vector<int>& A) {
      int ret = 0;
      unordered_map <lli, unordered_map <lli, lli> > dp, cnt;
      unordered_set <int> s (A.begin(), A.end());
      int n = A.size();
      for(int i = 1; i < n; i++){
         for(int j = i - 1; j >= 0; j--){
            lli diff = (lli)A[i] - (lli)A[j];
            if(diff <= INT_MIN || diff > INT_MAX) continue;
            int temp = dp[j].count(diff) ? dp[j][diff] : 0;
            ret += temp;
            if(s.count(A[i] + diff))dp[i][diff] += temp + 1;
         }
      }
      return ret;
   }
};
main(){
   Solution ob;
   vector<int> v = {2,4,6,8,10};
   cout << (ob.numberOfArithmeticSlices(v));
}

输入

{2,4,6,8,10}

输出

7

相关文章