🧠
Brute Force (Enumerate All Subsequences)
💡 This approach exists to understand the problem's combinatorial explosion and why naive enumeration is infeasible.
Intuition
Try all subsequences of length ≥ 3 and check if they are arithmetic. Count those that satisfy the condition.
Algorithm
- Generate all subsequences of length at least 3 using recursion or bitmask.
- For each subsequence, check if it is arithmetic by verifying equal differences.
- If arithmetic, increment the count.
- Return the total count.
💡 The challenge is the huge number of subsequences, making this approach impractical for large inputs.
from itertools import combinations
def numberOfArithmeticSlices(nums):
n = len(nums)
count = 0
for length in range(3, n+1):
for comb in combinations(range(n), length):
diff = nums[comb[1]] - nums[comb[0]]
arithmetic = True
for i in range(2, length):
if nums[comb[i]] - nums[comb[i-1]] != diff:
arithmetic = False
break
if arithmetic:
count += 1
return count
# Example usage
if __name__ == '__main__':
print(numberOfArithmeticSlices([2,4,6,8,10])) # Output: 7
Line Notes
from itertools import combinationsImport combinations to generate subsequences easily
for length in range(3, n+1)Only consider subsequences of length at least 3
for comb in combinations(range(n), length)Generate all index subsequences of given length
diff = nums[comb[1]] - nums[comb[0]]Calculate common difference for the subsequence
if nums[comb[i]] - nums[comb[i-1]] != diffCheck if difference is consistent for all pairs
import java.util.*;
public class Solution {
public int numberOfArithmeticSlices(int[] nums) {
int n = nums.length;
int count = 0;
for (int length = 3; length <= n; length++) {
int[] indices = new int[length];
count += backtrackCount(nums, indices, 0, 0, length);
}
return count;
}
private boolean isArithmetic(int[] nums, int[] indices) {
int diff = nums[indices[1]] - nums[indices[0]];
for (int i = 2; i < indices.length; i++) {
if (nums[indices[i]] - nums[indices[i - 1]] != diff) return false;
}
return true;
}
private int backtrackCount(int[] nums, int[] indices, int start, int depth, int length) {
if (depth == length) {
return isArithmetic(nums, indices) ? 1 : 0;
}
int count = 0;
for (int i = start; i < nums.length; i++) {
indices[depth] = i;
count += backtrackCount(nums, indices, i + 1, depth + 1, length);
}
return count;
}
public static void main(String[] args) {
Solution sol = new Solution();
System.out.println(sol.numberOfArithmeticSlices(new int[]{2,4,6,8,10})); // 7
}
}
Line Notes
for (int length = 3; length <= n; length++)Iterate over subsequence lengths starting from 3
private boolean isArithmeticHelper to check if a subsequence is arithmetic
for (int i = start; i < nums.length; i++)Generate all subsequences recursively
count += backtrackCount(...)Accumulate count of valid arithmetic subsequences
#include <iostream>
#include <vector>
using namespace std;
bool isArithmetic(const vector<int>& nums, const vector<int>& indices) {
int diff = nums[indices[1]] - nums[indices[0]];
for (int i = 2; i < indices.size(); i++) {
if (nums[indices[i]] - nums[indices[i - 1]] != diff) return false;
}
return true;
}
int backtrackCount(const vector<int>& nums, vector<int>& indices, int start, int depth, int length) {
if (depth == length) {
return isArithmetic(nums, indices) ? 1 : 0;
}
int count = 0;
for (int i = start; i < nums.size(); i++) {
indices[depth] = i;
count += backtrackCount(nums, indices, i + 1, depth + 1, length);
}
return count;
}
int numberOfArithmeticSlices(const vector<int>& nums) {
int n = nums.size();
int count = 0;
for (int length = 3; length <= n; length++) {
vector<int> indices(length);
count += backtrackCount(nums, indices, 0, 0, length);
}
return count;
}
int main() {
vector<int> nums = {2,4,6,8,10};
cout << numberOfArithmeticSlices(nums) << endl; // 7
return 0;
}
Line Notes
for (int length = 3; length <= n; length++)Loop over subsequence lengths starting at 3
bool isArithmeticCheck if given subsequence indices form arithmetic sequence
for (int i = start; i < nums.size(); i++)Generate subsequences recursively
count += backtrackCount(...)Sum counts of valid arithmetic subsequences
function numberOfArithmeticSlices(nums) {
const n = nums.length;
let count = 0;
function isArithmetic(indices) {
const diff = nums[indices[1]] - nums[indices[0]];
for (let i = 2; i < indices.length; i++) {
if (nums[indices[i]] - nums[indices[i - 1]] !== diff) return false;
}
return true;
}
function backtrack(indices, start, depth, length) {
if (depth === length) {
if (isArithmetic(indices)) count++;
return;
}
for (let i = start; i < n; i++) {
indices[depth] = i;
backtrack(indices, i + 1, depth + 1, length);
}
}
for (let length = 3; length <= n; length++) {
backtrack([], 0, 0, length);
}
return count;
}
// Example usage
console.log(numberOfArithmeticSlices([2,4,6,8,10])); // 7
Line Notes
for (let length = 3; length <= n; length++)Iterate over subsequence lengths starting at 3
function isArithmetic(indices)Check if subsequence is arithmetic
for (let i = start; i < n; i++)Generate subsequences recursively
if (isArithmetic(indices)) count++Increment count if subsequence is arithmetic
Enumerating all subsequences is exponential in n, and checking each subsequence takes linear time.
💡 For n=20, this means over a million subsequences, which is too large to compute in reasonable time.
Interview Verdict: TLE
This approach is too slow for large inputs but helps understand the problem's combinatorial nature.