lc1895 幻方
二维前缀和--->行列前缀和
class Solution {
public:
int largestMagicSquare(vector<vector<int>>& grid)
{
int m=grid.size(),n=grid[0].size();
vector<vector<int>> sum;
sum.resize(m + 1, vector<int>(n + 1));
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
++sum[i + 1][j + 1] = sum[i + 1][j] + sum[i][j + 1] - sum[i][j] + grid[i][j];++
}
}
int mx=1;
for(int k=min(m,n);k>=1;k--)
{
for(int r1=0;r1<=m-k;r1++)
{
for(int c1=0;c1<=n-k;c1++)
{
int target = sum[r1+1][c1+k] - sum[r1+1][c1] - sum[r1][c1+k] + sum[r1][c1];
bool ok=true;
// 检查所有行和
for(int i=0;i<k && ok;i++)
if(sum[r1+i+1][c1+k]-sum[r1+i+1][c1]-sum[r1+i][c1+k]+sum[r1+i][c1]!=target)
ok=false;
// 检查所有列和
for(int j=0;j<k && ok;j++)
if(sum[r1+k][c1+j+1]-sum[r1+k][c1+j]-sum[r1][c1+j+1]+sum[r1][c1+j]!=target)
ok=false;
// 检查主对角线
int diag1=0;
for(int i=0;i<k && ok;i++) diag1+=grid[r1+i][c1+i];
if(diag1!=target) ok=false;
// 检查副对角线
int diag2=0;
for(int i=0;i<k && ok;i++) diag2+=grid[r1+i][c1+k-1-i];
if(diag2!=target) ok=false;
if(ok) return k;
}
}
}
return mx;
}
};
行列前缀和的写法
行列检查
for(int x=0; x<k && ok; x++)
++ok &= (row[i+x][j+k]-row[i+x][j]==t); // 行++
正反对角线表示法
for(int x=0; x<k && ok; x++)
d1+=g[i+x][j+x];
++d2+=g[i+x][j+k-1-x];++
class Solution {
public:
int largestMagicSquare(vector<vector<int>>& g) {
int m = g.size(), n = g[0].size();
vector<vector<int>> row(m, vector<int>(n+1)), col(n, vector<int>(m+1));
// 预处理行/列前缀和
for(int i=0; i<m; i++) for(int j=0; j<n; j++) row[i][j+1] = row[i][j] + g[i][j];
for(int j=0; j<n; j++) for(int i=0; i<m; i++) col[j][i+1] = col[j][i] + g[i][j];
++for(int k=min(m,n); k>=1; k--) // 从大到小枚举++
++for(int i=0; i<=m-k; i++)++
++for(int j=0; j<=n-k; j++) {++
int t = row[i][j+k] - row[i][j]; // 第一行和为目标
bool ok=1;
for(int x=0; x<k && ok; x++)
ok &= (row[i+x][j+k]-row[i+x][j]==t); // 行
for(int y=0; y<k && ok; y++)
ok &= (col[j+y][i+k]-col[j+y][i]==t); // 列
int d1=0,d2=0;
for(int x=0; x<k && ok; x++) d1+=g[i+x][j+x], d2+=g[i+x][j+k-1-x];
++if(ok && d1==t && d2==t) return k;++
}
return 1;
}
};
lc1171
hash+presum
++组织结构:++
++unordered_map<int, ListNode*> presum;++
++// presum, node (memo)++
cur->next = presum[sum]->next;
class Solution {
//presum+hash
public:
ListNode* removeZeroSumSublists(ListNode* head)
{
ListNode* dummy = new ListNode(0);
dummy->next = head;
++unordered_map<int, ListNode*> prefix; // presum, node++
int sum = 0;
for (ListNode* cur = dummy; cur; cur = cur->next)
{
sum += cur->val;
prefix[sum] = cur;
}
sum = 0;
++for (ListNode* cur = dummy; cur; cur = cur->next)++
{
sum += cur->val;
++cur->next = prefix[sum]->next;++
}
return dummy->next;
}
};

lc659
hash模拟大法,记录使用
class Solution {
public:
bool isPossible(vector<int>& nums) {
unordered_map<int, int> cnt, end;
for (int num : nums) cnt[num]++;
for (int num : nums)
{
if (!cnt[num]) continue;
cnt[num]--;
if (end[num-1])
{
end[num-1]--; //use
end[num]++;
}
else if (cnt[num+1] && cnt[num+2]) {
cnt[num+1]--; //use
cnt[num+2]--;
end[num+2]++;
}
else
return false;
}
return true;
}
};