289 生命游戏
思路:1. 读题:每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律
2. 大体:类似于之前的图片过滤器,二维数组需要遍历一遍,否则不可能知道周围八个位置是多少个活细胞或死细胞 O(m*n)
3. 细节:需要同时进行死亡或者复活,则通过标记不同的数字,最后再统一处理
class Solution {
public:
void gameOfLife(vector<vector<int>>& board) {
int m = board.size() , n = board[0].size();
for(int i = 0 ; i < m ; i ++){
for(int j = 0 ; j < n ; j ++){
int count = 0 ;
for(int x = i - 1 ; x <= i+1 ; x++){
for(int y = j - 1 ; y <= j+1 ; y++){
if(x >= 0 && y >= 0 && x < m && y < n){
if(abs(board[x][y]) == 1){count++;}
}
}
}
if(board[i][j] == 1){
(count == 2+1 || count == 3+1) ? board[i][j] : board[i][j] = -1;
}else{
count == 3 ? board[i][j] = 2 : board[i][j];
}
}
}
for(int i = 0 ; i < m ; i++){
for(int j = 0 ; j < n ; j++){
if(board[i][j] == 2){board[i][j] = 1;}
else if(board[i][j] == -1 ){board[i][j] = 0;}
}
}
}
};
303 区域和检索 - 数组不可变 【积累】
经典前缀和例题:注意sums[0]和sums的长度
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];
}
};
/**
* Your NumArray object will be instantiated and called as such:
* NumArray* obj = new NumArray(nums);
* int param_1 = obj->sumRange(left,right);
*/
304 二维区域和检索 - 矩阵不可变 【积累】
二维前缀和
class NumMatrix {
public:
vector<vector<int>> sums;
NumMatrix(vector<vector<int>>& matrix) {
int m = matrix.size() , n = matrix[0].size();
sums.resize(m+1,vector<int>(n+1 , 0));
// 构建前缀和矩阵
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
sums[i][j] = matrix[i-1][j-1] + sums[i-1][j] + sums[i][j-1] - sums[i-1][j-1];
}
}
}
int sumRegion(int row1, int col1, int row2, int col2) {
return sums[row2 + 1][col2 + 1] - sums[row1][col2 + 1] - sums[row2 + 1][col1] + sums[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);
*/
238 除自身以外的数组乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。
题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。
请 不要使用除法,且在 O(n) 时间复杂度内完成此题。
思路:1. 题目:数组 nums之中任意元素的全部前缀元素和后缀的乘积
2. 大体:前缀和 后缀和 -->前缀积后缀积
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int n = nums.size();
vector<int> ans(n , 1);
//线性递推,左侧乘积 119题
for(int i = 1 ; i < n ;i++){
ans[i] = ans[i-1] * nums[i-1];
}
//反推,得到右侧
int right = 1;
for(int i = n - 1 ; i >= 0 ; --i){
ans[i] = ans[i] * right;
right *= nums[i];
}
return ans;
}
};
讨论区中的一个双指针答案:
//维护两个变量,beforeSum表示前缀和,afterSum表示后缀和
public int[] productExceptSelf(int[] nums) {
int n=nums.length;
int[] ans=new int[n];
Arrays.fill(ans,1);
int beforeSum=1;
int afterSum=1;
for(int i=0,j=n-1;i<n;i++,j--){
ans[i]*=beforeSum;
ans[j]*=afterSum;
beforeSum*=nums[i];
afterSum*=nums[j];
}
return ans;
}