1.前缀和,求取一个下标范围的值,只需要(right+1)-left的数组即可。(注意不能减去left+1,因为left处要包含在最后的结果中)
class NumArray {
public:
vector<int> sums;
NumArray(vector<int>& nums) {
int n=nums.size();
sums.resize(n+1);
for(int i=0;i<n;i++){
sums[i+1]=sums[i]+nums[i];
}
}
int sumRange(int left, int right) {
return sums[right+1]-sums[left];
}
};
2.
(1)三重循环暴力求解。
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int n=arr.size();
int sum=0;
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
if((j-i)%2==0){
for(int k=i;k<=j;k++){
sum+=arr[k];
}
}
}
}
return sum;
}
};
(2)和第一题一样可以采用前缀和。和暴力解法对比大致就是把第三重循环改了一下,让o(n3)变成了o(n2)。
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int n=arr.size();
vector<int>arrs;
arrs.resize(n+1);
for(int i=0;i<n;i++){
arrs[i+1]=arrs[i]+arr[i];
}
int sum=0;
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
if((j-i)%2==0){
sum+=arrs[j+1]-arrs[i];
}
}
}
return sum;
}
};
3.滑动窗口,通过left1和left2的差值确定满足条件的子数组数量。
class Solution {
public:
int numSubarraysWithSum(vector<int>& nums, int goal) {
int n = nums.size();
int left1 = 0, left2 = 0, right = 0;
int sum1 = 0, sum2 = 0;
int ret = 0;
while (right < n) {
sum1 += nums[right];
while (left1 <= right && sum1 > goal) {
sum1 -= nums[left1];
left1++;
}
sum2 += nums[right];
while (left2 <= right && sum2 >= goal) {
sum2 -= nums[left2];
left2++;
}
ret += left2 - left1;
right++;
}
return ret;
}
};
4.假设最少需要买i件产品,i从1开始遍历,知道出现满足ik或者ik-r整除10即可,然后break,输出最小的i即可。(k为商品单价,r为硬币面值)
#include <bits/stdc++.h>
using namespace std;
const int N=1e5;
int main(){
int k,r,mins;
cin>>k>>r;
for(int i=1;i<=N;i++){
if((i*k)%10==0 || (i*k-r)%10==0){
mins=i;
break;
}
}
cout<<mins<<endl;
return 0;
}