每天刷两道题——第五天

1.1下降路径最小和

给你一个 n x n n x n nxn 整数矩阵 g r i d grid grid ,请你返回非零偏移下降路径数字和的最小值。其中非零偏移下降路径定义为:从 g r i d grid grid 数组中的每一行选择一个数字,且按顺序选出来的数字中,相邻数字不在原数组的同一列

输入:grid = [[1,2,3],[4,5,6],[7,8,9]]
输出:13
解释:所有非零偏移下降路径包括:
[1,5,9], [1,5,7], [1,6,7], [1,6,8],
[2,4,8], [2,4,9], [2,6,7], [2,6,8],
[3,4,8], [3,4,9], [3,5,7], [3,5,9]
下降路径中数字和最小的是 [1,5,7] ,所以答案是 13 。

代码

1.for _ in range的用法

#_可以替换成任何符合规定的字符串
a = ['a' for _ in range(5)]
#['a', 'a', 'a', 'a', 'a']
b = [['a' for _ in range(2)]for _ in range(3)]
#[['a', 'a'],['a', 'a'],['a', 'a']]

2.解题代码
动态规划:令状态 f [ i ] [ j ] f[i][j] f[i][j]表示从数组 g r i d grid grid的前 i i i 行中的每一行选择一个数字,并且第 i i i行选择的数字为 g r i d [ i ] [ j ] grid[i][j] grid[i][j] 时,可以得到的路径和最小值。 f [ i ] [ j ] f[i][j] f[i][j] 可以从第 i − 1 i−1 i1 行除了 f [ i − 1 ] [ j ] f[i−1][j] f[i1][j] 之外的任意状态转移而来,状态转移方程:
f [ i ] [ j ] = { g r i d [ 0 ] [ j ] if  i = = 0 m i n ( f [ i − 1 ] [ k ] ) + g r i d [ i ] [ j ] if  i   / = 0 , j   / = k f[i][j]= \begin{cases} grid[0][j] &\text{if } i==0\\ min(f[i-1][k])+grid[i][j]&\text{if } i\mathrlap{\,/}{=}0,j\mathrlap{\,/}{=}k \end{cases} f[i][j]={grid[0][j]min(f[i1][k])+grid[i][j]if i==0if i/=0,j/=k

class question1:
    def minFallingPathSum(self,grid):
        n=len(grid)  #数组的深度
        f=[[10**4 for _ in range(n)] for _ in range(n)] 
        #n*n的二维数组,假设数组的每个输入的都小于10**4=10000
        for i in range(n):
            f[0][i]=grid[0][i]
        for i in range(n):
            for j in range(n):
                for k in range(n):
                    if j!=k:
                        f[i][j]=min(f[i][j],f[i-1][k]+grid[i][j])
                        #当前的f[i][j]为上一状态到这里的路径最小和
                        #因此还需要和不同选择的f[i][j]作对比,选最小的更新
        return min(f[n-1])

q = question1()
print(q.minFallingPathSum([[1,2,3],[4,5,6],[7,8,9]]))

1.2统计参与通信的服务器

这里有一幅服务器分布图,服务器的位置标识在 m ∗ n m * n mn 的整数矩阵网格 g r i d grid grid 中,1 表示单元格上有服务器,0 表示没有。如果两台服务器位于同一行或者同一列,我们就认为它们之间可以进行通信。请你统计并返回能够与至少一台其他服务器进行通信的服务器的数量
每天刷两道题——第五天_第1张图片

输入:grid = [[1,1,0,0],[0,0,1,0],[0,0,1,0],[0,0,0,1]]
输出:4
解释:第一行的两台服务器互相通信,第三列的两台服务器互相通信,但右下角的服务器无法与其他服务器通信

哈希表:用来实现键值对结构,将任意长度的数据映射到有限长度的域上。

代码

from collections import Counter
class question1:
 def countServers(self,grid):
        m,n=len(grid[0]),len(grid)
        rows,cols=Counter(),Counter() #哈希表,键值对
        for i in range(m): #计算每行每列有多少个服务器
            for j in range(n):
                if grid[i][j]==1:
                    rows[i]+=1  #直接添加,时间复杂度为O(1)
                    cols[j]+=1
        ans=0
        for i in range(m):
            for j in range(n):
                if grid[i][j]==1 and (rows[i]>1 or cols[j]>1):
               #如果当前有服务器并且他的行或者列上有其他的服务器就可以认为该服务器可以通信
                    ans+=1
        return ans
q = question1()
print(q.countServers([[1,1,0,0],[0,0,1,0],[0,0,1,0],[0,0,0,1]]))

Counter函数

Counter目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。

    def testCounter(self):
        c = Counter("abcdefgab")
        c1 = Counter({'a': 4, 'b': 2})  # 从一个字典对象创建
        c2 = Counter(a=3, b=5)  # 从一组键值对创{'b': 5, 'a': 3}
        print(c["a"])  #2
        lc=list(c) # 将c中的键转为列表
        sc=set(c)  # 将c中的键转为set
        dc=dict(c) # 将c中的键转为字典
        print("lc={},sc={}.dc={},c1={},c2={},c={}".format(lc, sc, dc,c1,c2,c))

你可能感兴趣的:(每日刷题挑战,python)