leetcode 1252题 解法 奇数值单元格的数目

奇数值单元格的数目
给你一个 n 行 m 列的矩阵,最开始的时候,每个单元格中的值都是 0。

另有一个索引数组 indices,indices[i] = [ri, ci] 中的 ri 和 ci 分别表示指定的行和列(从 0 开始编号)。

你需要将每对 [ri, ci] 指定的行和列上的所有单元格的值加 1。

请你在执行完所有 indices 指定的增量操作后,返回矩阵中 「奇数值单元格」 的数目。

解题思路:indices 里面的一个一个的值 表示 的 意思 要理解。题目说的很清楚。

解法1:

直接按照题目的意思一遍一遍的把数累加上去。

可以优化算法的地方:

注意一点因为判断奇数,所以 如果现在是 0 ,那么加 1 之后是 1。如果是 1 ,加 1 之后 是 0 .因为偶数么,相当于0.

def oddCells(n, m, indices):
    lista=[[0 for i in range(m)] for i2 in range(n)] #初始化二维数组
    
    for x in indices:
        for y in range(m): #遍历行
            if lista[x[0]][y]==0:
                lista[x[0]][y]=1
            else:
                lista[x[0]][y]=0      
        
        for y2 in range(n):#遍历列
            if lista[y2][x[1]]==0:
                lista[y2][x[1]]=1
            else:
                lista[y2][x[1]]=0
           
    sum=0
    for x in range(n):  #最后统计一遍所有的 1 
        for y in range(m):
            sum+=lista[x][y]        

    return sum
    
oddCells(2,2,[[1,1],[0,0]])

此种解法,好像只能击败 15%以上的选手,所有该算法有改进的空间。

解法2:

如果从开始的时候就对 indices 里面的数值进行优化,效果会更好些。
分别定义2个list a1,a2,用来记录 indices 里面描述行 和 列的 信息。
先把行的值 都添加进 a1,
如果 x 在 a1 里面了,那么 两相抵消。直接把 a1里面的x删除了即可。如果不在a1里面,就添加进a1。
如果 x 在 a2 里面了,那么 两相抵消。直接把 a2里面的x删除了即可。如果不在a2里面,就添加进a2。

最后
a1 相当于需要修改 1 次的行的集合
a2 相当于需要修改 1 次的列的集合

然后,开始把 改 加 1 的,放进一个新的二维数组lista。

最后 再遍历一遍里面的里面的所有1

def oddCells(n, m, indices):
    lista=[[0 for i in range(m)] for i2 in range(n)] #初始化二维数组
    
    a1=[]
    a2=[]
    
    for x in indices:
        if x[0] in a1:
            a1.remove(x[0])
        else:
            a1.append(x[0])
        
        if x[1] in a2:
            a2.remove(x[1])
        else:
            a2.append(x[1])
            
    for x in a1:
        for y in range(m):
            if lista[x][y]==0:
                lista[x][y]=1
            else:
                lista[x][y]=0
    
    for x in a2:
        for y in range(n):
            if lista[y][x]==0:
                lista[y][x]=1
            else:
                lista[y][x]=0
           
    suma=0
    for x in range(n):
        for y in range(m):
            suma+=lista[x][y]        

    return suma
    
oddCells(2,3,[[0,1],[1,1]])

但是这种接法也只是击败了85%的选手。

解法3

如果我们可以确定 需要变换的 行数 和列数。那就意味着,行数*m+列数*n 就是变换后的点的数量。
当然里面有重复的,
重点: 重复的包括两个方面的
1、行列交汇的点 被重复计算了,所有减去 行数*列数
2、重复的点 结果应该是2,变化了2次,所以还要 再减去 行数*列数

def oddCells(n, m, indices):
   
    a1=[]
    a2=[]
    
    for x in indices:
        if x[0] in a1:
            a1.remove(x[0])
        else:
            a1.append(x[0])
        
        if x[1] in a2:
            a2.remove(x[1])
        else:
            a2.append(x[1])    
    x=len(a1)
    y=len(a2)
    return x*m+y*n-2*x*y
    
oddCells(2,2,[[1,1],[0,0]])

这次的结果才最终击败了99%的选手!

posted on 2020-09-01 22:27  耀扬  阅读(178)  评论(0编辑  收藏  举报

导航