鱼C论坛

 找回密码
 立即注册
查看: 2305|回复: 21

Python:每日一题 298

[复制链接]
发表于 2020-1-1 17:35:50 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
今天的题目:


给一个 01 矩阵,求不同的岛屿的个数。

0 代表海,1 代表岛,如果两个 1 相邻,那么这两个 1 属于同一个岛。只考虑上下左右为相邻。

示例 1:

输入:
[
  [1,1,0,0,0],
  [0,1,0,0,1],
  [0,0,0,1,1],
  [0,0,0,0,0],
  [0,0,0,0,1]
]
输出:3
示例 2:

输入:
[
  [1,1]
]
输出:1


欢迎大家一起答题!

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-1-1 17:44:08 | 显示全部楼层
本帖最后由 18463102026 于 2020-1-1 18:49 编辑
  1. def fun297(s):
  2.     if len(s) == 0 or len(s[0]) == 0:
  3.         return 0
  4.     count, m, n = 0, len(s), len(s[0])
  5.     def fun(i, j):
  6.         if i < 0 or i >= m or j < 0 or j >= n or s[i][j] != 1:
  7.             return
  8.         s[i][j] = 0
  9.         fun(i, j - 1)
  10.         fun(i - 1, j)
  11.         fun(i + 1, j)
  12.         fun(i, j + 1)
  13.     for i in range(m):
  14.         for j in range(n):
  15.             if s[i][j] == 1:
  16.                 count += 1
  17.                 fun(i, j)
  18.     return count
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
zltzlt + 3 + 3 + 3 157 ms

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-1 18:29:30 | 显示全部楼层
本帖最后由 Croper 于 2020-1-1 18:32 编辑
  1. def func298(grid)->int:
  2.     if len(grid)==0 or len(grid[0])==0:
  3.         return 0

  4.     ret=0
  5.     width=len(grid[0])
  6.     height=len(grid)

  7.     #嗯,把岛炸掉
  8.     def burnisland(i,j):
  9.         if i<0 or i>=height or j<0 or j>=width:
  10.             return
  11.         if grid[i][j]==0:
  12.             return
  13.         grid[i][j]=0
  14.         burnisland(i+1,j)
  15.         burnisland(i-1,j)
  16.         burnisland(i,j+1)
  17.         burnisland(i,j-1)

  18.    #遇到一个岛炸一个岛
  19.     for i in range(height):
  20.         for j in range(width):
  21.             if grid[i][j]==0:
  22.                 continue
  23.             ret+=1
  24.             burnisland(i,j)
  25.     return ret
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
zltzlt + 3 + 3 + 3 160 ms

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-1 19:45:53 | 显示全部楼层
抢滩登陆模拟器~~~
  1. def solve(world):
  2.     num = 0
  3.     lx,ly = len(world),(len(world[0]) if world else 0)
  4.     the_map = [[0]*ly]*lx
  5.     def explore(x,y):#探索岛屿并绘制地图,炸岛什么的不利于生存
  6.         nonlocal the_map
  7.         #print('调试',x,y,lx,ly)
  8.         if world[x][y]:
  9.             if the_map[x][y]:
  10.                 return
  11.             else:
  12.                 the_map[x][y] = num
  13.             if x:
  14.                 explore(x-1,y)
  15.             if lx - x > 1:
  16.                 explore(x+1,y)
  17.             if y:
  18.                 explore(x,y-1)
  19.             if ly - y > 1:
  20.                 explore(x,y+1)
  21.     for x in range(lx):
  22.         for y in range(ly):
  23.             if world[x][y] and (not the_map[x][y]):
  24.                 num += 1
  25.                 explore(x,y)
  26.     return num
  27. if __name__ == '__main__':
  28.     print('示例1 输出:',solve([
  29.   [1,1,0,0,0],
  30.   [0,1,0,0,1],
  31.   [0,0,0,1,1],
  32.   [0,0,0,0,0],
  33.   [0,0,0,0,1]
  34. ]))
  35.     print('示例2 输出:',solve([
  36.   [1,1]
  37. ]))
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-1 20:03:56 | 显示全部楼层
  1. def f298(M):
  2.     res,I,J=0,len(M),len(M[0])
  3.     def dp(i,j):
  4.         if i in range(I) and j in range(J) and M[i][j]==1:
  5.             M[i][j]=0
  6.             dp(i,j-1)
  7.             dp(i-1,j)
  8.             dp(i+1,j)
  9.             dp(i,j+1)
  10.     for i in range(I):
  11.         for j in range(J):
  12.             if M[i][j]:
  13.                 res+=1
  14.                 dp(i,j)
  15.     return res
复制代码

DP都差不多

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
zltzlt + 3 + 3 + 3 253 ms

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-1 21:25:55 | 显示全部楼层
本帖最后由 TJBEST 于 2020-1-2 14:54 编辑

哈哈,我编了一个非常麻烦的方法,但是结果正确,哈哈
  1. def fun298(matrix):
  2.     m = len(matrix)
  3.     n = len(matrix[0])
  4.     count = 1
  5.     ##改写矩阵
  6.     for i in range(0,m):
  7.         for j in range(0,n):
  8.             if matrix[i][j]!=0:
  9.                 if i!=0 and j!=0:
  10.                     temp = max((matrix[i][j-1],matrix[i-1][j]))
  11.                     if temp > 1:
  12.                         matrix[i][j] = temp
  13.                     else:
  14.                         count = count + 1
  15.                         matrix[i][j] = count
  16.                 elif i == 0 and  j != 0:
  17.                     temp = matrix[i][j-1]
  18.                     if temp > 1:
  19.                        matrix[i][j] = temp
  20.                     else:
  21.                         count = count + 1
  22.                         matrix[i][j] = count
  23.                 elif i !=0 and j == 0:
  24.                     temp = matrix[i-1][j]
  25.                     if temp > 1:
  26.                         matrix[i][j] = temp
  27.                     else:
  28.                         count = count + 1
  29.                         matrix[i][j] = count
  30.                 else:
  31.                     count = count + 1
  32.                     matrix[i][j] = count
  33.     ##统计矩阵
  34.     listSet = set()
  35.     for i in range(0,m):
  36.         for j in range(0,n):
  37.             if matrix[i][j]!=0:
  38.                 if i!=(m-1) and j!=(n-1):
  39.                     temp1 = matrix[i][j]
  40.                     temp2 = matrix[i][j+1]
  41.                     temp3 = matrix[i+1][j]
  42.                     if temp2 != 0:
  43.                         listSet.add(tuple(sorted((temp1,temp2))))
  44.                     elif temp3 != 0:
  45.                         listSet.add(tuple(sorted((temp1,temp3))))
  46.                     else:
  47.                         listSet.add(tuple([temp1,temp1]))
  48.                 elif i == (m-1) and j!=(n-1):
  49.                     temp1 = matrix[i][j]
  50.                     temp2 = matrix[i][j+1]
  51.                     if temp2 != 0:
  52.                         listSet.add(tuple(sorted((temp1,temp2))))
  53.                     else:
  54.                         listSet.add(tuple([temp1,temp1]))
  55.                 elif i != (m-1) and j ==(n-1):
  56.                     temp1 = matrix[i][j]
  57.                     temp3 = matrix[i+1][j]
  58.                     if  temp3 != 0:
  59.                         listSet.add(tuple(sorted((temp1,temp3))))
  60.                     else:
  61.                         listSet.add(tuple([temp1,temp1]))                    
  62.                 else:
  63.                     temp1 = matrix[i][j]
  64.                     listSet.add(tuple([temp1,temp1]))  
  65.     #计算多少个小岛
  66.     setCount = []
  67.     for eachmin in range(2,count + 1):
  68.         eachSet = {eachmin}
  69.         for eachTuple in listSet:
  70.             if eachmin == eachTuple[0]:
  71.                 eachSet.add(eachTuple[1])
  72.         setCount.append(eachSet)
  73.     for index in range(count - 2,-1,-1):
  74.         temp = setCount[index]
  75.         for inner in range(0,index):
  76.             if (temp & setCount[inner])!=set():
  77.                 setCount[inner] = setCount[inner] | temp
  78.                 del setCount[index]
  79.     return len(setCount)
  80.         
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-2 10:38:00 | 显示全部楼层
比较高级了啊,仔细看看,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-2 20:57:51 | 显示全部楼层
本帖最后由 archlzy 于 2020-1-3 00:36 编辑
  1. import copy
  2. def fun298(target_list):
  3.    
  4.     def change(_m,_n, temp,m,n):
  5.         if 0<=_m<m and 0<=_n <n:
  6.             if temp[_m][_n] == 0:
  7.                 return
  8.             else:
  9.                 temp[_m][_n] = 0
  10.                 change(_m-1,_n,temp,m,n)
  11.                 change(_m,_n-1,temp,m,n)
  12.                 change(_m+1,_n,temp,m,n)
  13.                 change(_m,_n+1,temp,m,n)               
  14.         else:
  15.             return
  16.         
  17.     temp = copy.deepcopy(target_list)
  18.     m = len(target_list)
  19.     n = len(target_list[0])
  20.     count = 0
  21.     for _m in range(m):
  22.         for _n in range(n):
  23.             if temp[_m][_n] == 0:
  24.                 pass
  25.             else:
  26.                 count += 1
  27.                 change(_m,_n, temp,m,n)
  28.     return count
复制代码



来个不是递归的

  1. import copy
  2. def fun298(tar_list):
  3.     m = len(tar_list)
  4.     n = len(tar_list[0])
  5.     temp = copy.deepcopy(tar_list)
  6.     count_list = [[0 for i in j] for j in temp]
  7.     count=0
  8.     res = []
  9.     for _m in range(m):
  10.         for _n in range(n):
  11.             if temp[_m][_n] == 0:
  12.                 pass
  13.             else:
  14.                 if _m==0:
  15.                     if (temp[_m][_n-1] if _n>0 else 0) == 0:
  16.                         count += 1
  17.                         count_list[_m][_n] = count
  18.                     else:
  19.                         count_list[_m][_n] = count_list[_m][_n-1]
  20.                 elif _n == 0:
  21.                     if temp[_m-1][_n] == 0:
  22.                         count += 1
  23.                         count_list[_m][_n] = count
  24.                     else:
  25.                         count_list[_m][_n] = count_list[_m-1][_n]
  26.                 elif temp[_m][_n-1] and temp[_m-1][_n] == 1:
  27.                         if count_list[_m-1][_n] == count_list[_m][_n-1]:
  28.                              count_list[_m][_n] = count_list[_m][_n-1]
  29.                         else:
  30.                             count_list[_m][_n] = count_list[_m-1][_n]
  31.                             temp_count = count_list[_m][_n-1]
  32.                             for i in range(_m+1):
  33.                                 for j in range(_n+1):
  34.                                     if count_list<i>[j] == temp_count:
  35.                                         count_list<i>[j] = count_list[_m-1][_n]
  36.                 elif temp[_m][_n-1] == 1:
  37.                     count_list[_m][_n] = count_list[_m][_n-1]
  38.                 elif temp[_m-1][_n] == 1:
  39.                     count_list[_m][_n] = count_list[_m-1][_n]
  40.                 else:
  41.                     count += 1
  42.                     count_list[_m][_n] = count
  43.     for i in count_list:
  44.         res += i
  45.     res = set(res)
  46.     return len(res) - 1</i></i>
复制代码

评分

参与人数 1荣誉 +2 鱼币 +2 收起 理由
zltzlt + 2 + 2

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-2 21:28:23 | 显示全部楼层

解答错误

输入:[
[0,1,0],
[1,0,1],
[0,1,0]
]
输出:3
预期结果:4
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-2 21:30:14 | 显示全部楼层
TJBEST 发表于 2020-1-1 21:25
哈哈,我编了一个非常麻烦的方法,但是结果正确,哈哈

确实挺麻烦。。

输入大数据超时
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-2 21:43:52 | 显示全部楼层
zltzlt 发表于 2020-1-2 21:30
确实挺麻烦。。

输入大数据超时

就先这样吧,我测试 大概 0.025ms一个点 差不多矩阵 m*n= 40000 大概1秒
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-2 22:58:43 | 显示全部楼层
这道题如果不用递归是不是做出来就超时了哦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-2 23:42:28 | 显示全部楼层
本帖最后由 阴阳神万物主 于 2020-1-2 23:43 编辑
zltzlt 发表于 2020-1-2 21:28
解答错误

输入:[


                               
登录/注册后可看大图
忘记检查登记的地图了……

                               
登录/注册后可看大图

忘却了地址相通的特性。
  1. def solve(world):
  2.     num = 0
  3.     lx,ly = len(world),(len(world[0]) if world else 0)
  4.     the_map = [[0]*ly for i in range(lx)]
  5.     def explore(x,y):#探索岛屿并绘制地图,炸岛什么的不利于生存
  6.         nonlocal the_map
  7.         if world[x][y]:
  8.             if the_map[x][y]:
  9.                 return
  10.             else:
  11.                 #print('调试',x,y,lx,ly)
  12.                 the_map[x][y] = num
  13.             if x:
  14.                 explore(x-1,y)
  15.             if lx - x > 1:
  16.                 explore(x+1,y)
  17.             if y:
  18.                 explore(x,y-1)
  19.             if ly - y > 1:
  20.                 explore(x,y+1)
  21.     for x in range(lx):
  22.         for y in range(ly):
  23.             if world[x][y] and (not the_map[x][y]):
  24.                 num += 1
  25.                 explore(x,y)
  26. '''
  27.     for line in the_map:
  28.         print(line)
  29. '''
  30.     return num
  31. if __name__ == '__main__':
  32.     '''
  33.     print('示例1 输出:',solve([
  34.   [1,1,0,0,0],
  35.   [0,1,0,0,1],
  36.   [0,0,0,1,1],
  37.   [0,0,0,0,0],
  38.   [0,0,0,0,1]
  39. ]))
  40.     print('示例2 输出:',solve([
  41.   [1,1]
  42. ]))
  43.     '''
  44.     print(solve([
  45. [0,1,0],
  46. [1,0,1],
  47. [0,1,0]
  48. ]))
复制代码

评分

参与人数 1荣誉 +9 鱼币 +9 收起 理由
zltzlt + 9 + 9 151 ms

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-2 23:43:14 | 显示全部楼层
不用递归也行啊。其实省去了函数调用,理论上还应该快点,而且不会浪费宝贵的栈空间。就是写着麻烦。
《数据结构于算法》的书上应该都有,二叉树周游的非递归写法,
其实是一个思想,手动进栈出栈。递归只是把这一系列工作交给了函数调用来处理罢了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-2 23:53:12 | 显示全部楼层
本帖最后由 Croper 于 2020-1-2 23:59 编辑

不用递归的
  1. def func298(grid)->int:
  2.     if len(grid)==0 or len(grid[0])==0:
  3.         return 0

  4.     ret=0
  5.     width=len(grid[0])
  6.     height=len(grid)

  7.     #嗯,把岛炸掉
  8.     def burnisland(i,j):
  9.         if i<0 or i>=height or j<0 or j>=width:
  10.             return
  11.         if grid[i][j]==0:
  12.             return
  13.         stk=[(i,j)]
  14.         grid[i][j]=0
  15.         offset=((-1,0),(1,0),(0,-1),(0,1))
  16.         while (len(stk)>0):
  17.             (y,x)=stk.pop()
  18.             for (y1,x1) in offset:
  19.                 y1+=y
  20.                 x1+=x
  21.                 if 0<=x1<width and 0<=y1<height and grid[y1][x1]==1:
  22.                     grid[y1][x1]=0
  23.                     stk.append((y1,x1))


  24.    #遇到一个岛炸一个岛
  25.     for i in range(height):
  26.         for j in range(width):
  27.             if grid[i][j]==0:
  28.                 continue
  29.             ret+=1
  30.             burnisland(i,j)
  31.     return ret
复制代码

评分

参与人数 1荣誉 +8 鱼币 +8 收起 理由
zltzlt + 8 + 8

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-2 23:59:47 | 显示全部楼层
#coding:utf-8

b=[
  [1,1,0,0,0],
  [0,1,0,0,1],
  [0,0,0,1,1],
  [0,0,0,0,0],
  [0,0,0,0,1]
]

row=len(b[0])
column=len(b)

def func(x,i,j):
    if i<0 or j<0 or i>=row or j>=column:
        return 0
    elif x[i][j]==0 or x[i][j]==2:
        return 0
    else:
        x[i][j]=2
        func(x,i-1,j)
        func(x,i+1,j)
        func(x,i,j-1)
        func(x,i,j+1)

if __name__ =="__main__":
    num=0
    x=b
    for i in range(row):
        for j in range(column):
            if x[i][j]==1:
                num+=1
                func(x,i,j)
    print x
    print num

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-3 09:33:54 | 显示全部楼层
膜拜各位大佬,这个应该是图像处理领域的连通性检测
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-3 10:48:07 | 显示全部楼层
  1. def fun298(chart):

  2.     def nearland_check(chart,x,y):
  3.         nearby = [i for i in [[x-1,y],[x+1,y],[x,y-1],[x,y+1]] if i[0] in range(len(chart)) and i[1] in range(len(chart[x]))]
  4.         return [i for i in nearby if chart[i[0]][i[1]]]
  5.         
  6.     islands_count = 0
  7.     islands = []
  8.     for i in range(len(chart)):
  9.         for j in range(len(chart[i])):
  10.             if chart[i][j] and [i,j] not in islands:
  11.                 islands_count += 1
  12.                 near_land = nearland_check(chart,i,j)
  13.                 islands.extend(near_land)
  14.                 for n in near_land:
  15.                     if nearland_check(chart,n[0],n[1]):
  16.                         islands.extend(nearland_check(chart,n[0],n[1]))
  17.     return islands_count
复制代码

评分

参与人数 1荣誉 +2 鱼币 +2 收起 理由
zltzlt + 2 + 2

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-4 17:28:17 | 显示全部楼层
archlzy 发表于 2020-1-2 20:57
来个不是递归的

解答错误

输入:[[1,1,0,0,0],[0,1,0,0,1],[0,0,0,1,1],[0,0,0,0,0],[0,0,0,0,1]]
输出:4
预期结果:3
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-4 17:30:06 | 显示全部楼层

请使用 Python 3。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 16:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表