子数组|状态机dp
lc576
状态机dp
class Solution {
public:
int findPaths(int m, int n, int N, int i, int j) {
int MOD = 1000000007;
if (N == 0) { return 0; }
vector<vector<vector<unsigned long long int>>> dp(m + 2, vector<vector<unsigned long long int>>(n + 2, vector<unsigned long long int>(N + 1, 0)));
for (int i = 0; i <= m + 1; i++) {
dp[i][0][0] = 1;
dp[i][n + 1][0] = 1;
}
for (int i = 0; i <= n + 1; i++) {
dp[0][i][0] = 1;
dp[m + 1][i][0] = 1;
}
for (int k = 1; k <= N; k++) {
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
dp[i][j][k] = (dp[i - 1][j][k - 1] + dp[i + 1][j][k - 1] + \
dp[i][j - 1][k - 1] + dp[i][j + 1][k - 1]) % MOD;
}
}
}
int sum = 0;
for (int k = 1; k <= N; k++) {
sum = (sum + dp[i + 1][j + 1][k]) % MOD;
}
return sum;
}
};
lc754
不断累加正整数,找到最小的n
使得累加和大于等于目标数且与目标数的差为偶数
此时n就是最小移动次数

class Solution {
public:
int reachNumber(int target) {
target = abs(target); // 利用对称性,只考虑正数情况
int n = 0;
int sum = 0;
while (sum < target || (sum - target) % 2 != 0) {
n++;
sum += n;
}
return n;
}
};
lc9
同向双指针
class Solution {
public:
int numSubarrayProductLessThanK(vector<int> &nums, int k) {
if (k <= 1)
return 0;
int n = nums.size(), ans = 0, prod = 1, left = 0;
for (int right = 0; right < n; ++right) {
prod *= nums[right];
while (prod >= k) // 不满足要求
prod /= nums[left++];
ans += right - left + 1;
}
return ans;
}
};
lcr10
前缀和hash
class Solution {
public:
int subarraySum(vector<int>& nums, int k)
{
unordered_map<int, int> preSumFreq;
preSumFreq[0] = 1;
int preSum = 0;
int cnt = 0;
for (int num : nums) {
preSum += num;
if (preSumFreq.count(preSum - k))
cnt += preSumFreq[preSum - k];
preSumFreq[preSum]++;
}
return cnt;
}
};
