7.14 数组中等&简单 289 303 304 238

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;
    }
  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值