diff --git a/leetcode/DIRECTORY.md b/leetcode/DIRECTORY.md index 8533e899..1bddc049 100644 --- a/leetcode/DIRECTORY.md +++ b/leetcode/DIRECTORY.md @@ -124,3 +124,4 @@ | 2256 | [Minimum Average Difference](https://leetcode.com/problems/minimum-average-difference/) | [C](./src/2256.c) | Medium | | 2270 | [Number of Ways to Split Array](https://leetcode.com/problems/number-of-ways-to-split-array/) | [C](./src/2270.c) | Medium | | 2304 | [Minimum Path Cost in a Grid](https://leetcode.com/problems/minimum-path-cost-in-a-grid/) | [C](./src/2304.c) | Medium | +| 2501 | [Longest Square Streak in an Array](https://leetcode.com/problems/longest-square-streak-in-an-array/description/) | [C](./src/2501.c) | Medium | diff --git a/leetcode/src/2501.c b/leetcode/src/2501.c new file mode 100644 index 00000000..87cfa270 --- /dev/null +++ b/leetcode/src/2501.c @@ -0,0 +1,52 @@ +#define max(a,b) (((a)>(b))?(a):(b)) + +int longestSquareStreakDp(int* numsSet, int numsSetSize, int* dp, long num){ + if (dp[num] != 0){ + return dp[num]; + } + + long numSquare = num * num; + + dp[num] = 1; + if (numSquare <= numsSetSize && numsSet[numSquare] == 1){ + dp[num] += longestSquareStreakDp(numsSet, numsSetSize, dp, numSquare); + } + + return dp[num]; +} + +// Dynamic approach. Up -> down. +// Runtime: O(numsSize) +// Space: O(max(nums)) +int longestSquareStreak(int* nums, int numsSize){ + // Find nums maximum + int numMax = 0; + for(int i = 0; i < numsSize; i++){ + numMax = max(numMax, nums[i]); + } + + int* numsSet = calloc(numMax + 1, sizeof(int)); + int* dp = calloc(numMax + 1, sizeof(int)); + + // Init set of nums + for(int i = 0; i < numsSize; i++){ + numsSet[nums[i]] = 1; + } + + // Find result + int result = -1; + for(int i = 0; i < numsSize; i++){ + long num = nums[i]; + long numSquare = num * num; + + if (numSquare > numMax || numsSet[numSquare] == 0){ + continue; + } + + result = max(result, 1 + longestSquareStreakDp(numsSet, numMax, dp, numSquare)); + } + + free(dp); + free(numsSet); + return result; +}