leetcode:1252. 奇数值单元格的数目

题目来源

题目描述

在这里插入图片描述
在这里插入图片描述

题目解析

暴力模拟:

c++

int oddCells(int n, int m, vector<vector<int>>& indices) {
    vector<vector<int>> res(n, vector<int>(m));
    for (auto cur : indices) {
        for (int i = 0; i < m; i++)
            res[cur[0]][i]++;
        for (int i = 0; i < n; i++)
            res[i][cur[1]]++;
    }

    int cnt = 0;
    for(int i = 0;i<n;i++){
        for(int j = 0;j<m;j++){
            cnt += res[i][j]%2;
        }
    }
    return cnt;
}

在这里插入图片描述

java

        public static  int oddCells(int n, int m, int[][] indices) {
            int[][] arr = new int[n][m];

            for (int i = 0; i < indices.length; i++){
                int col = indices[i][0]; // 第i行第一个元素
                int lin = indices[i][1];

                for (int a = 0; a < m; a++){
                    arr[col][a]++;
                }

                for (int a = 0; a < n; a++){
                    arr[a][lin]++;
                }
            }

            int num = 0;
            for (int i = 0; i < arr.length; i++){
                for (int j = 0 ; j < arr[i].length; j++){
                    if (arr[i][j]%2 != 0){
                        num++;
                    }
                }
            }

            return  num;
        }

在这里插入图片描述

阴影面积法

一次遍历中记录奇数的行数(odd_rows)和列数(odd_cols)。

此时奇数行和奇数列不重叠的部分为奇数,重叠的部分则为偶数。

下面有多种数学思路,提2个:

1.循环出来以后用数学求解。
返回值 = odd_rows * m + odd_cols * n - 2 * odd_rows * odd_cols
解释:先把行上的所有奇数与列上的所有奇数相加(先不管重叠部分)。再减去重叠的部分(偶数),由于重叠部分在奇数行和奇数列中分别被当作奇数加了一次,所以减去时需要乘以2。

2.这样想也行(结果与上相同):
返回值 = odd_rols * (m - odd_cols) + odd_cols * (n - odd_rows)
解释:将奇数行不重叠的部分(奇数)与奇数列不重叠的部分(奇数)相加。

        public static  int oddCells(int n, int m, int[][] indices) {
            boolean[] bal = new boolean[n];
            boolean[] vert = new boolean[m];

            int row = 0;
            int line = 0;
            for (int i = 0; i < indices.length; i++){
                int a = indices[i][0];
                int b = indices[i][1];
                /*
                * 初始: false, 为0
                *  第一次加:变成奇数, !false=true, row++; 为1, bal[a] = true
                * 第二次加:变成偶数, row--; 为2,
                * */
                if (!bal[a]){  //
                    row++;
                    bal[a] = true;
                }else{
                    row--;
                    bal[a] = false;
                }

                if (!vert[b]){
                    line++;
                    vert[b] = true;
                }else{
                    line--;
                    vert[b] = false;
                }
            }
            // row * m
            return  row * m + line * n - 2 * row * line;
        }

在这里插入图片描述

给定一个整组 nums 和一个目标 target,要求在组中找出两个的和等于目标,并返回这两个的索引。 思路1:暴力法 最简单的思路是使用两层循环遍历组的所有组合,判断两个的和是否等于目标。如果等于目标,则返回这两个的索引。 此方法的时间复杂度为O(n^2),空间复杂度为O(1)。 思路2:哈希表 为了优化时间复杂度,可以使用哈希表来存储组中的元素和对应的索引。遍历组,对于每个元素nums[i],我们可以通过计算target - nums[i]的,查找哈希表中是否存在这个差。 如果存在,则说明找到了两个的和等于目标,返回它们的索引。如果不存在,将当前元素nums[i]和它的索引存入哈希表中。 此方法的时间复杂度为O(n),空间复杂度为O(n)。 思路3:双指针 如果组已经排序,可以使用双指针的方法来求解。假设组从小到大排序,定义左指针left指向组的第一个元素,右指针right指向组的最后一个元素。 如果当前两个指针指向的的和等于目标,则返回它们的索引。如果和小于目标,则将左指针右移一位,使得和增大;如果和大于目标,则将右指针左移一位,使得和减小。 继续移动指针,直到找到两个的和等于目标或者左指针超过了右指针。 此方法的时间复杂度为O(nlogn),空间复杂度为O(1)。 以上三种方法都可以解决问题,选择合适的方法取决于具体的应用场景和要求。如果组规模较小并且不需要考虑额外的空间使用,则暴力法是最简单的方法。如果组较大或者需要优化时间复杂度,则哈希表或双指针方法更合适。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值