classSolution { publicintarithmeticTriplets(int[] nums, int diff) { intans=0; intn= nums.length; for (inti=0; i < n; i++) { for (intj= i + 1; j < n; j++) { if (nums[j] - nums[i] != diff) { continue; } for (intk= j + 1; k < n; k++) { if (nums[k] - nums[j] == diff) { ans++; } } } } return ans; } }
[sol1-C#]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
publicclassSolution { publicintArithmeticTriplets(int[] nums, int diff) { int ans = 0; int n = nums.Length; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (nums[j] - nums[i] != diff) { continue; } for (int k = j + 1; k < n; k++) { if (nums[k] - nums[j] == diff) { ans++; } } } } return ans; } }
classSolution { public: intarithmeticTriplets(vector<int>& nums, int diff){ int ans = 0; int n = nums.size(); for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (nums[j] - nums[i] != diff) { continue; } for (int k = j + 1; k < n; k++) { if (nums[k] - nums[j] == diff) { ans++; } } } } return ans; } };
[sol1-C]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
intarithmeticTriplets(int* nums, int numsSize, int diff) { int ans = 0; for (int i = 0; i < numsSize; i++) { for (int j = i + 1; j < numsSize; j++) { if (nums[j] - nums[i] != diff) { continue; } for (int k = j + 1; k < numsSize; k++) { if (nums[k] - nums[j] == diff) { ans++; } } } } return ans; }
[sol1-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
var arithmeticTriplets = function(nums, diff) { let ans = 0; const n = nums.length; for (let i = 0; i < n; i++) { for (let j = i + 1; j < n; j++) { if (nums[j] - nums[i] !== diff) { continue; } for (let k = j + 1; k < n; k++) { if (nums[k] - nums[j] === diff) { ans++; } } } } return ans; };
复杂度分析
时间复杂度:O(n^3),其中 n 是数组 nums 的长度。使用三重循环暴力枚举需要 O(n^3) 的时间。
空间复杂度:O(1)。只需要常数的额外空间。
方法二:哈希集合
由于给定的数组 nums 是严格递增的,因此数组中不存在重复元素,不存在两个相同的算术三元组。
对于数组 nums 中的元素 x,如果 x + \textit{diff 和 x + 2 \times \textit{diff 都在数组中,则存在一个算术三元组,其中的三个元素分别是 x、x + \textit{diff 和 x + 2 \times \textit{diff,因此问题转换成计算数组 nums 中有多少个元素可以作为算术三元组的最小元素。
将数组中的所有元素都加入哈希集合之后,遍历数组并统计满足 x + \textit{diff 和 x + 2 \times \textit{diff 都在哈希集合中的元素 x 的个数,即为算术三元组的数目。
[sol2-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution { publicintarithmeticTriplets(int[] nums, int diff) { Set<Integer> set = newHashSet<Integer>(); for (int x : nums) { set.add(x); } intans=0; for (int x : nums) { if (set.contains(x + diff) && set.contains(x + 2 * diff)) { ans++; } } return ans; } }
[sol2-C#]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
publicclassSolution { publicintArithmeticTriplets(int[] nums, int diff) { ISet<int> set = new HashSet<int>(); foreach (int x in nums) { set.Add(x); } int ans = 0; foreach (int x in nums) { if (set.Contains(x + diff) && set.Contains(x + 2 * diff)) { ans++; } } return ans; } }
[sol2-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classSolution { public: intarithmeticTriplets(vector<int>& nums, int diff){ unordered_set<int> hashSet; for (int x : nums) { hashSet.emplace(x); } int ans = 0; for (int x : nums) { if (hashSet.count(x + diff) && hashSet.count(x + 2 * diff)) { ans++; } } return ans; } };
intarithmeticTriplets(int* nums, int numsSize, int diff) { HashItem *hashSet = NULL; for (int i = 0; i < numsSize; i++) { hashAddItem(&hashSet, nums[i]); } int ans = 0; for (int i = 0; i < numsSize; i++) { if (hashFindItem(&hashSet, nums[i] + diff) && hashFindItem(&hashSet, nums[i] + 2 * diff)) { ans++; } } hashFree(&hashSet); return ans; }
[sol2-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13
var arithmeticTriplets = function(nums, diff) { const set = newSet(); for (const x of nums) { set.add(x); } let ans = 0; for (const x of nums) { if (set.has(x + diff) && set.has(x + 2 * diff)) { ans++; } } return ans; };
复杂度分析
时间复杂度:O(n),其中 n 是数组 nums 的长度。需要遍历数组两次,每次将元素加入哈希集合与判断元素是否在哈希集合中的时间都是 O(1)。
intarithmeticTriplets(int* nums, int numsSize, int diff){ int ans = 0; int n = numsSize; for (int i = 0, j = 1, k = 2; i < n - 2 && j < n - 1 && k < n; i++) { j = MAX(j, i + 1); while (j < n - 1 && nums[j] - nums[i] < diff) { j++; } if (j >= n - 1 || nums[j] - nums[i] > diff) { continue; } k = MAX(k, j + 1); while (k < n && nums[k] - nums[j] < diff) { k++; } if (k < n && nums[k] - nums[j] == diff) { ans++; } } return ans; }