class Solution {
public:
int fib(int n) {
if (n < 2) {
return n;
}
int p = 0, q = 0, r = 1;
for (int i = 2; i <= n; ++i) {
p = q;
q = r;
r = p + q;
}
return r;
}
};
class Solution {
public:
int tribonacci(int n) {
if(n<2)return n;
int hair = 0, pre = 1, cur = 1, ans = cur;
for(int i = 3; i <= n; ++i){
ans = hair + pre + cur;
hair = pre;
pre = cur;
cur = ans;
}
return ans;
}
};
给你一个整数 n ,请你找出并返回第 n 个 丑数 。
丑数 就是只包含质因数 2、3 和/或 5 的正整数。
class Solution {
public:
int nthUglyNumber(int n) {
long ugly=1;
vector<long> factors={2L,3L,5L};
unordered_set<long> s;
priority_queue<long,vector<long>,greater<long>> p;
s.insert(1L);
p.push(1L);
for(int i=0;i<n;++i){
ugly=p.top();
p.pop();
for(int factor:factors){
long tmp=ugly*factor;
if(s.find(tmp)==s.end()){
s.insert(tmp);
p.push(tmp);
}
}
}
return ugly;
}
};
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> ans;
for(int i=1;i<=numRows;++i){
vector<int> tmp(i,1);
for(int j=1;j<i-1;++j){
tmp[j]=ans[i-2][j-1]+ans[i-2][j];
}
ans.emplace_back(tmp);
}
return ans;
}
};
class Solution {
public:
vector<int> getRow(int rowIndex) {
vector<int> ans(rowIndex+1);
ans[0]=1;
for(int i=0;i<=rowIndex;++i){
for(int j=i;j>0;--j){
ans[j]+=ans[j-1];
}
}
return ans;
}
};
class Solution {
public:
int climbStairs(int n) {
int p = 0, q = 0, r = 1;
for (int i = 1; i <= n; ++i) {
p = q;
q = r;
r = p + q;
}
return r;
}
};
int minCostClimbingStairs(vector<int>& cost) {
int len = cost.size();
int dp[len+1];
dp[0]=0;
dp[1]=0;
for(int i=2;i<len+1;++i){
dp[i] = min(dp[i-2]+cost[i-2],dp[i-1]+cost[i-1]);
}
return dp[len];
}
121. 买卖股票的最佳时机 - 力扣(LeetCode)
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len=prices.size();
int pre=prices[0],res=0;
for(auto price:prices){
res=max(price-pre,res);
pre=min(pre,price);
}
return res;
}
};
122. 买卖股票的最佳时机 II - 力扣(LeetCode)
class Solution {
public:
int maxProfit(vector<int>& prices) {
int ans = 0;
int n = prices.size();
for (int i = 1; i < n; ++i) {
ans += max(0, prices[i] - prices[i - 1]);
}
return ans;
}
};
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
int dp[n][2];
dp[0][0] = 0, dp[0][1] = -prices[0];
for (int i = 1; i < n; ++i) {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
}
return dp[n - 1][0];
}
};
309. 最佳买卖股票时机含冷冻期 - 力扣(LeetCode)
class Solution {
public:
//[1,2,4]
//[2,1,4]
int maxProfit(vector<int>& prices) {
int len=prices.size();
int dp[len][2];
dp[0][0]=0;//第一天没买股票
dp[0][1]=-prices[0];//第一天买了股票
for(int i=1;i<len;++i){
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]);
dp[i][1]=(i-2>=0)?(max(dp[i-1][1],dp[i-2][0]-prices[i])):max(dp[i-1][1],-prices[i]);
}
return dp[len-1][0];
}
};
714. 买卖股票的最佳时机含手续费 - 力扣(LeetCode)
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int len=prices.size();
int dp[len][2];
dp[0][0]=0;
dp[0][1]=-prices[0];
for(int i=1;i<len;++i){
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]-fee);
dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);
}
return dp[len-1][0];
}
};
class Solution {
private:
vector<int> val;
vector<vector<int>> rec;
public:
int solve(int left,int right){
if(left>=right-1){
return 0;
}
if(rec[left][right]!=-1){
return rec[left][right];
}
for(int i=left+1;i<right;++i){
int sum=val[i]*val[left]*val[right];
sum+=solve(left,i)+solve(i,right);
rec[left][right]=max(rec[left][right],sum);
}
return rec[left][right];
}
int maxCoins(vector<int>& nums) {
int n=nums.size();
val.resize(n+2);
val[0]=val[n+1]=1;
for(int i=1;i<=n;++i){
val[i]=nums[i-1];
}
rec.resize(n+2,vector<int>(n+2,-1));
return solve(0,n+1);
}
};
class Solution {
public:
int maxCoins(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> rec(n + 2, vector<int>(n + 2));
vector<int> val(n + 2);
val[0] = val[n + 1] = 1;
for (int i = 1; i <= n; i++) {
val[i] = nums[i - 1];
}
for (int i = n - 1; i >= 0; i--) {
for (int j = i + 2; j <= n + 1; j++) {
for (int k = i + 1; k < j; k++) {
int sum = val[i] * val[k] * val[j];
sum += rec[i][k] + rec[k][j];
rec[i][j] = max(rec[i][j], sum);
}
}
}
return rec[0][n + 1];
}
};
class Solution {
/**
[0]
[1,2]
[2,1,1,2]
*/
public:
int rob(vector<int>& nums) {
if(nums.size()==0)return 0;
if(nums.size()==1)return nums[0];
vector<int> dp(nums.size()+1,0);
dp[0]=nums[0];dp[1]=max(nums[1],dp[0]);
for(int i=2;i<nums.size();i++){
dp[i] = max(dp[i-2]+nums[i],dp[i-1]);
}
return dp[nums.size()-1];
}
};
class Solution {
public:
int rob(vector<int>& nums) {
if (nums.empty()) {
return 0;
}
int size = nums.size();
if (size == 1) {
return nums[0];
}
int first = nums[0], second = max(nums[0], nums[1]);
for (int i = 2; i < size; i++) {
int temp = second;
second = max(first + nums[i], second);
first = temp;
}
return second;
}
};
打家劫舍
class Solution {
public:
int robRange(vector<int>& nums, int start, int end) {
int first = nums[start], second = max(nums[start], nums[start + 1]);
for (int i = start + 2; i <= end; i++) {
int temp = second;
second = max(first + nums[i], second);
first = temp;
}
return second;
}
int rob(vector<int>& nums) {
int length = nums.size();
if (length == 1) {
return nums[0];
} else if (length == 2) {
return max(nums[0], nums[1]);
}
return max(robRange(nums, 0, length - 2), robRange(nums, 1, length - 1));
}
};
有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的体积是c,价值是w。将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。
购物单_牛客题霸_牛客网
#include
using namespace std;
/**
6000 15
100 3 0
400 5 0
300 5 0
1400 2 3
500 2 2
800 2 3
1400 5 0
300 5 0
1400 3 0
500 2 0
1800 4 0
440 5 10
1340 5 10
430 3 0
500 2 0
*/
int main(){
int N,m;//N钱数,m物品个数
cin>>N>>m;
int val[60][3]={0},cos[60][3]={0};//分别代表价格、物品重要度、主件标识(0为主键)
int total[3200]={0};//题目提示都是十的倍数
//最多两个附件
for(int i=1;i<=m;++i){
int v,p,q;
cin>>v>>p>>q;
if(q!=0){
//不是主件
if(val[q][1]==0){
//第一个附件
val[q][1]=v*p;
cos[q][1]=v;
}else{
val[q][2]=v*p;
cos[q][2]=v;
}
}else{
val[i][0]=v*p;
cos[i][0]=v;
}
}
for(int i=1;i<=m;++i){//遍历所有物品
for(int j=N/10;j>=cos[i][0]/10;--j){
//只选主件
if(j>=cos[i][0]/10){
total[j]=max(total[j],val[i][0]+total[j-cos[i][0]/10]);
}
//选主+1附件
int tmp=(cos[i][0]+cos[i][1])/10;
if(cos[i][1]!=0&&j>=tmp){
total[j]=max(total[j],val[i][0]+val[i][1]+total[j-tmp]);
}
//主+2附件
tmp=(cos[i][0]+cos[i][1]+cos[i][2])/10;
if(cos[i][2]!=0&&j>=tmp){
total[j]=max(total[j],val[i][0]+val[i][1]+val[i][2]+total[j-tmp]);
}
}
}
cout<<total[N/10]<<endl;
return 0;
}
https://leetcode-cn.com/problems/shopping-offers/
class Solution {
private:
int ans=INT_MAX;
int getNeedsCost(vector<int>& price, vector<int>& needs){
int total=0;
for(int i=0;i<needs.size();++i){
total+=needs[i]*price[i];
}
return total;
}
void shooppingSpecials(int cost, vector<int>& price, vector<vector<int>>& special, vector<int>& needs){
//获得当前方案的开销(补充剩余物品)
int total=cost+getNeedsCost(price,needs);
ans=total<ans?total:ans;
//遍历每种情况
for(int i=0;i<special.size();++i){
//满足条件时
bool flag=true;
vector<int>& tmp=special[i];
for(int i=0;i<tmp.size()-1;++i){
if(needs[i]-tmp[i]<0){
flag=false;
break;
}
}
if(flag){
for(int i=0;i<tmp.size()-1;++i){
needs[i]-=tmp[i];
}
shooppingSpecials(cost+tmp[tmp.size()-1],price,special,needs);
//回溯
for(int i=0;i<tmp.size()-1;++i){
needs[i]+=tmp[i];
}
}
}
}
public:
int shoppingOffers(vector<int>& price, vector<vector<int>>& special, vector<int>& needs) {
//先找大礼包并补充剩余物品
shooppingSpecials(0,price,special,needs);
return ans;
}
};
class Solution {
public:
map<vector<int>, int> memo;
int shoppingOffers(vector<int>& price, vector<vector<int>>& special, vector<int>& needs) {
int n = price.size();
// 过滤不需要计算的大礼包,只保留需要计算的大礼包
vector<vector<int>> filterSpecial;
for (auto & sp : special) {
int totalCount = 0, totalPrice = 0;
for (int i = 0; i < n; ++i) {
totalCount += sp[i];
totalPrice += sp[i] * price[i];
}
if (totalCount > 0 && totalPrice > sp[n]) {
filterSpecial.emplace_back(sp);
}
}
return dfs(price, special, needs, filterSpecial, n);
}
// 记忆化搜索计算满足购物清单所需花费的最低价格
int dfs(vector<int> price,const vector<vector<int>> & special, vector<int> curNeeds, vector<vector<int>> & filterSpecial, int n) {
if (!memo.count(curNeeds)) {
int minPrice = 0;
for (int i = 0; i < n; ++i) {
minPrice += curNeeds[i] * price[i]; // 不购买任何大礼包,原价购买购物清单中的所有物品
}
for (auto & curSpecial : filterSpecial) {
int specialPrice = curSpecial[n];
vector<int> nxtNeeds;
for (int i = 0; i < n; ++i) {
if (curSpecial[i] > curNeeds[i]) { // 不能购买超出购物清单指定数量的物品
break;
}
nxtNeeds.emplace_back(curNeeds[i] - curSpecial[i]);
}
if (nxtNeeds.size() == n) { // 大礼包可以购买
minPrice = min(minPrice, dfs(price, special, nxtNeeds, filterSpecial, n) + specialPrice);
}
}
memo[curNeeds] = minPrice;
}
return memo[curNeeds];
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/shopping-offers/solution/da-li-bao-by-leetcode-solution-p1ww/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount+1,INT_MAX/3);
dp[0]=0;
for(int i=1;i<amount+1;++i){
for(int coin:coins){
if(i-coin>=0){
dp[i]=min(dp[i],dp[i-coin]+1);
}
}
}
return dp[amount]==INT_MAX/3?-1:dp[amount];
}
};
class Solution {
public:
int change(int amount, vector<int>& coins) {
vector<int> dp(amount+1);
dp[0]=1;
for(int coin:coins){
for(int i=coin;i<amount+1;++i){
if(i-coin>=0&&dp[i-coin]>0){
dp[i]+=dp[i-coin];
}
}
}
return dp[amount];
}
};
最大子序和
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int pre = 0, maxAns = nums[0];
for (const auto &x: nums) {
pre = max(pre + x, x);
maxAns = max(maxAns, pre);
}
return maxAns;
}
};
918. 环形子数组的最大和 - 力扣(LeetCode)
class Solution {
public:
int maxSubarraySumCircular(vector<int>& nums) {
int len=nums.size();
//先计算,没有环形的情况下的最大子数组和
int ans=nums[0],pre=nums[0];
for(int i=1;i<len;++i){
pre=nums[i]+max(pre,0);
ans=max(ans,pre);
}
//cout<
//考虑环形,既左端加右端
//1、计算右端和
// rightsums[i] = A[i] + A[i+1] + ... + A[N-1]
vector<int> rightSum(len,0);
rightSum[len-1]=nums[len-1];
for(int i=len-2;i>=0;--i){
rightSum[i]=rightSum[i+1]+nums[i];
}
//2、计算右端和最大值
vector<int> rightMax(len,0);
rightMax[len-1]=nums[len-1];
for(int i=len-2;i>=0;--i){
rightMax[i]=max(rightMax[i+1],rightSum[i]);
}
//3、计算环形最大和
int leftSum=0;
for(int i=0;i<len-2;i++){
leftSum+=nums[i];
ans=max(ans,leftSum+rightMax[i+2]);
}
return ans;
}
};
class Solution {
public:
string longestPalindrome(string s) {
int begin=0;
int s_max=1;
int len=s.size();
vector<vector<int>> dp(len+1,vector<int>(len+1));
for(int i=0;i<len;++i){
dp[i][i]=1;
}
for(int L=2;L<=len;++L){
for(int i=0;i<len;++i){
//右边界
int j=i+L-1;
if(j>=len)break;
if(s[i]!=s[j]){
dp[i][j]=0;
}else{
if(j-i<3){
dp[i][j]=true;
}else{
dp[i][j]=dp[i+1][j-1];
}
}
if(dp[i][j]&&j-i+1>s_max){
s_max=j-i+1;
begin=i;
}
}
}
return s.substr(begin,s_max);
}
};
class Solution {
public:
string longestPalindrome(string s) {
int begin=0;
int s_max=1;
int len=s.size();
vector<vector<int>> dp(len+1,vector<int>(len+1));
for(int i=len-1;i>=0;--i){
dp[i][i]=1;
for(int j=i+1;j<len;++j){
// cout<
if(s[i]==s[j]){
if(j-i<3){
dp[i][j]=1;
}else{
dp[i][j]=dp[i+1][j-1];
}
if(dp[i][j]==1&&j-i+1>s_max){
begin=i;
s_max=j-i+1;
}
// cout<<"dp["<
}else{
dp[i][j]=0;
}
}
}
return s.substr(begin,s_max);
}
};
class Solution {
public:
string longestPalindrome(string s) {
int len=s.size();
if(len==0||len==1)
return s;
int start=0;//记录回文子串起始位置
int end=0;//记录回文子串终止位置
int mlen=0;//记录最大回文子串的长度
for(int i=0;i<len;i++)
{
int len1=expendaroundcenter(s,i,i);//一个元素为中心
int len2=expendaroundcenter(s,i,i+1);//两个元素为中心
mlen=max(max(len1,len2),mlen);
if(mlen>end-start+1)
{
start=i-(mlen-1)/2;
end=i+mlen/2;
}
}
return s.substr(start,mlen);
//该函数的意思是获取从start开始长度为mlen长度的字符串
}
private:
int expendaroundcenter(string s,int left,int right)
//计算以left和right为中心的回文串长度
{
int L=left;
int R=right;
while(L>=0 && R<s.length() && s[R]==s[L])
{
L--;
R++;
}
return R-L-1;
}
};
class Solution {
public:
int longestPalindromeSubseq(string A) {
int len=A.size();
vector<vector<int>> dp(len,vector<int>(len));
for(int i=len-1;i>=0;--i){
dp[i][i]=1;
for(int j=i+1;j<len;++j){
if(A[i]==A[j]){
if(j-i+1<3){dp[i][j]=2;continue;}
dp[i][j]=dp[i+1][j-1]+2;
}else{
dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
}
}
}
return dp[0][len-1];
}
};
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int len=nums.size();
vector<int> dp(len);
int ans=1;
for(int i=0;i<len;++i){
dp[i]=1;
for(int j=0;j<i;++j){
if(nums[j]<nums[i]){
dp[i]=max(dp[i],dp[j]+1);
}
}
ans=max(ans,dp[i]);
}
return ans;
}
};
class Solution {
public:
int numDecodings(string s) {
int len=s.size();
vector<int> dp(len+1);
dp[0]=1;
for(int i=1;i<len+1;++i){
if(s[i-1]!='0'){
dp[i]+=dp[i-1];
}
if(i>1&&s[i-2]!='0'&&((s[i-2]-'0')*10+(s[i-1]-'0')<=26)){
dp[i]+=dp[i-2];
}
}
return dp[len];
}
};
class Solution {
public:
int numTrees(int n) {
vector<int> ans(n+1,0);
ans[0]=1,ans[1]=1;
for(int i=2;i<=n;++i){
for(int j=1;j<=i;j++){
ans[i]+=ans[j-1]*ans[i-j];
}
}
return ans[n];
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<TreeNode*> generateTrees(int start, int end) {
if (start > end) {
return { nullptr };//不能返回空{},会导致for循环遍历不到元素
}
vector<TreeNode*> allTrees;
// 枚举可行根节点
for (int i = start; i <= end; i++) {
// 获得所有可行的左子树集合
vector<TreeNode*> leftTrees = generateTrees(start, i - 1);
// 获得所有可行的右子树集合
vector<TreeNode*> rightTrees = generateTrees(i + 1, end);
// 从左子树集合中选出一棵左子树,从右子树集合中选出一棵右子树,拼接到根节点上
for (auto& left : leftTrees) {
for (auto& right : rightTrees) {
TreeNode* currTree = new TreeNode(i);
currTree->left = left;
currTree->right = right;
allTrees.emplace_back(currTree);
}
}
}
return allTrees;
}
vector<TreeNode*> generateTrees(int n) {
if (!n) {
return {};
}
return generateTrees(1, n);
}
};
class Solution {
public:
int minFallingPathSum(vector<vector<int>>& matrix) {
int ans=INT_MAX;
int len=matrix.size();
for(int i=len-2;i>=0;--i){
for(int j=0;j<len;++j){
int bst=matrix[i+1][j];
if(j<len-1){
bst=min(bst,matrix[i+1][j+1]);
}
if(j>0){
bst=min(bst,matrix[i+1][j-1]);
}
matrix[i][j]+=bst;
}
}
for(int j=0;j<len;++j){
ans=min(ans,matrix[0][j]);
}
return ans;
}
};
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
int ans=INT_MAX;
for(int i=triangle.size()-2;i>=0;--i){
for(int j=0;j<triangle[i].size();++j){
int best=min(triangle[i+1][j],triangle[i+1][j+1]);
triangle[i][j]+=best;
}
}
for(int i=0;i<triangle[0].size();++i){
ans=min(ans,triangle[0][i]);
}
return ans;
}
};
class Solution {
public:
int uniquePaths(int m, int n) {
int dp[m+1][n+1];
for(int i=0;i<m;++i){
dp[i][0]=1;
}
for(int j=0;j<n;++j){
dp[0][j]=1;
}
for(int i=1;i<m;++i){
for(int j=1;j<n;++j){
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}
};
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m=obstacleGrid.size(),n=obstacleGrid[0].size();
vector<vector<int>> dp(m+1,vector<int>(n+1));
for(int i=0;i<m;++i){
if(obstacleGrid[i][0]!=1){
dp[i][0]=1;
}else{
break;
}
}
for(int j=0;j<n;++j){
if(obstacleGrid[0][j]!=1){
dp[0][j]=1;
}else{
break;
}
}
for(int i=1;i<m;++i){
for(int j=1;j<n;++j){
if(obstacleGrid[i][j]==1){
dp[i][j]=0;
// cout<
continue;
}
dp[i][j]=dp[i-1][j]+dp[i][j-1];
// cout<
}
// cout<
}
return dp[m-1][n-1];
}
};
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int m=grid.size();
int n=grid[0].size();
for(int i=1;i<m;++i){
grid[i][0]+=grid[i-1][0];
}
for(int j=1;j<n;++j){
grid[0][j]+=grid[0][j-1];
}
for(int i=1;i<m;++i){
for(int j=1;j<n;++j){
grid[i][j]+=min(grid[i-1][j],grid[i][j-1]);
}
}
return grid[m-1][n-1];
}
};
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
int m=matrix.size();
int n=matrix[0].size();
int ans=0;
vector<vector<int>> dp(m,vector<int>(n));
for(int i=0;i<m;++i){
for(int j=0;j<n;++j){
dp[i][j]=matrix[i][j]-'0';
if(dp[i][j]==1)ans=1;
}
}
for(int i=1;i<m;++i){
for(int j=1;j<n;++j){
if(dp[i][j]==1){
int len_a=dp[i-1][j];
int len_b=dp[i][j-1];
int len_min=min(len_a,len_b);
if(len_min==0)dp[i][j]=1;
else dp[i][j]=(dp[i-len_min][j-len_min]>0?len_min+1:len_min);
ans=max(dp[i][j],ans);
}
// cout<
}
// cout<
}
return ans*ans;
}
};
计算字符串的距离_牛客题霸_牛客网
https://www.nowcoder.com/practice/3959837097c7413a961a135d7104c314?tpId=37&&tqId=21275&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking
#include
using namespace std;
//空间可以优化成O(n)
int main() {
string s1, s2;
while (cin >> s1 >> s2) {
vector<vector<int>> dp(s1.size() + 1, vector<int>(s2.size() + 1, 0));
for (int i = 1; i <= s2.length(); i++) dp[0][i] = i;
for (int i = 1; i <= s1.length(); i++) dp[i][0] = i;
for(int i=1;i<=s1.length();i++)
for (int j = 1; j <= s2.length(); j++) {
int min1 = min(dp[i - 1][j], dp[i][j - 1]) + 1;//加一个字符
dp[i][j] = min((s1[i - 1] == s2[j - 1] ? 0 : 1) + dp[i - 1][j - 1], min1);//修改字符
}
cout << dp[s1.size()][s2.size()] << endl;
}
}
class Solution {
public:
vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {
vector<vector<int>> ans(mat.size(),vector<int>(mat[0].size()));
for(int i=0;i<mat.size();++i){
for(int j=0;j<mat[0].size();++j){
// cout<<"i="<
int tmp=0;
for(int m=i-k;m<=i+k;++m){
for(int n=j-k;n<=j+k;++n){
// cout<
if(m>=0&&m<mat.size()&&n>=0&&n<mat[0].size()){
tmp+=mat[m][n];
}
}
}
ans[i][j]=tmp;
}
}
return ans;
}
};
class Solution {
public:
vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int K) {
int m = mat.size(), n = mat[0].size();
// 1. 计算行前缀和
vector<vector<int>> rowPrefix(m, vector<int>(n + 1, 0));
for (int i = 0; i < m; ++i) {
for (int j = 1; j <= n; ++j) {
rowPrefix[i][j] = rowPrefix[i][j-1] + mat[i][j-1];
}
}
// 2. 行前缀和加快 该行 [j-K, j+K] 列之和查询
vector<vector<int>> ans(m, vector<int>(n, 0));
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
// 由于 i-K < 0 或 i+K >= m,因此行最大有效区间为 [max(i-K, 0), min(i+K, m-1)]
for (int r = max(i-K, 0); r <= min(i+K, m-1); ++r) {
// 由于 j-K < 0 或 j+K >= n,因此最大有效区间为 [max(j-K, 0), min(j+K, n-1)]
ans[i][j] += rowPrefix[r][min(j+K, n-1)+1] - rowPrefix[r][max(j-K, 0)];
// for (int c = j - K; c <= j + K; ++c) {
// if (0 <= r && r < m && 0 <= c && c < n) // 检验合法坐标
// ans[i][j] += mat[r][c];
// }
}
}
}
return ans;
}
};
作者:boille
链接:https://leetcode-cn.com/problems/matrix-block-sum/solution/you-qian-ru-shen-bao-li-xing-lie-qian-zh-5503/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int K) {
int m = mat.size(), n = mat[0].size();
vector<vector<int>> prefix(m + 1, vector<int>(n + 1, 0));
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
prefix[i][j] = prefix[i-1][j] + prefix[i][j-1] - prefix[i-1][j-1] + mat[i-1][j-1];
}
}
vector<vector<int>> ans(m, vector<int>(n, 0));
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
// 计算左上角坐标 (row1, col1) 和右下角坐标 (row2, col2)
int row1 = max(i - K, 0), col1 = max(j - K, 0);
int row2 = min(i + K, m - 1), col2 = min(j + K, n - 1);
ans[i][j] = prefix[row2+1][col2+1] - prefix[row2+1][col1] - prefix[row1][col2+1] + prefix[row1][col1];
}
}
return ans;
}
};
作者:boille
链接:https://leetcode-cn.com/problems/matrix-block-sum/solution/you-qian-ru-shen-bao-li-xing-lie-qian-zh-5503/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class NumMatrix {
private:
vector<vector<int>> sum;
public:
NumMatrix(vector<vector<int>>& matrix) {
sum.resize(matrix.size()+1,vector<int>(matrix[0].size()+1));
for(int i=1;i<=matrix.size();++i){
for(int j=1;j<=matrix[0].size();++j){
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+matrix[i-1][j-1];
}
}
}
int sumRegion(int row1, int col1, int row2, int col2) {
return sum[row2+1][col2+1]-sum[row1][col2+1]-sum[row2+1][col1]+sum[row1][col1];
}
};
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix* obj = new NumMatrix(matrix);
* int param_1 = obj->sumRegion(row1,col1,row2,col2);
*/