题目意思是返回一个数组中等差数列的个数,其中等差数列element 个数必须大于等于3.
我的想法:基于647. Palindromic Substrings中的奇 偶count方法,即对于数组中每个元素,向两边奇展开/偶展开,就能找到所有符合要求子集。
感觉奇 偶count法很适合遍历数组,str然后找出所有子集.
代码如下:
int cal(int* A,int start,int end,int size){ int count=0; int temp=(start==end)?A[start-1]-A[start]:A[start]-A[end]; while(start>=1 && end<=size-2 && temp==A[end]-A[end+1] && temp==A[start-1]-A[start]){ start--;end++;count++; } return count; } int numberOfArithmeticSlices(int* A, int ASize) { int count=0; if(ASize<3)return 0; for(int i=1;i<ASize-1;i++){ count+=cal(A,i,i,ASize); count+=cal(A,i,i+1,ASize); } return count; }
别人的方法:
1 int numberOfArithmeticSlices(int* A, int ASize) { 2 int i, cnt = 0, sum = 0; 3 if (ASize < 3) 4 return 0; 5 for (i = 2; i < ASize; i++) { 6 if (A[i-1]-A[i-2] == A[i]-A[i-1]) { 7 cnt += 1; 8 sum += cnt; 9 } 10 else 11 cnt = 0; 12 } 13 return sum; 14 }
cnt+=1;sum+=cnt;其实就是DP的状态转移方程。
可以将 cnt 看作 前边已经有 cnt个等差数列了 也就是说前边存在一个(cnt+2)个元素的等差数列。
所以当此时的 i 满足等差时 相当于 总的等差数列要增加 (cnt)个, 长度分别是3,4,5......cnt+2的等差数列。
F(N) = F(N-1) + cnt;
还有一种DP解法 C++:
1 class Solution { 2 public: 3 int numberOfArithmeticSlices(vector<int>& A) { 4 int n = A.size(); 5 if (n < 3) return 0; 6 vector<int> dp(n, 0); // dp[i] means the number of arithmetic slices ending with A[i] 7 if (A[2]-A[1] == A[1]-A[0]) dp[2] = 1; // if the first three numbers are arithmetic or not 8 int result = dp[2]; 9 for (int i = 3; i < n; ++i) { 10 // if A[i-2], A[i-1], A[i] are arithmetic, then the number of arithmetic slices ending with A[i] (dp[i]) 11 // equals to: 12 // the number of arithmetic slices ending with A[i-1] (dp[i-1], all these arithmetic slices appending A[i] are also arithmetic) 13 // + 14 // A[i-2], A[i-1], A[i] (a brand new arithmetic slice) 15 // it is how dp[i] = dp[i-1] + 1 comes 16 if (A[i]-A[i-1] == A[i-1]-A[i-2]) 17 dp[i] = dp[i-1] + 1; 18 result += dp[i]; // accumulate all valid slices 19 } 20 return result; 21 } 22 };