[leetcode] Python(13)--01 矩阵(542)、钥匙和房间(841)、寻找数组的中心索引(724)、至少是其他数字两倍的最大数(747)

从零开始的力扣(第十三天)~

1.01 矩阵

给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。

两个相邻元素间的距离为 1 。

示例 1:
输入:
0 0 0
0 1 0
0 0 0

输出:
0 0 0
0 1 0
0 0 0

示例 2:
输入:
0 0 0
0 1 0
1 1 1

输出:
0 0 0
0 1 0
1 2 1

注意:
给定矩阵的元素个数不超过 10000。
给定矩阵中至少有一个元素是 0。
矩阵中的元素只在四个方向上相邻: 上、下、左、右。
—————————————————————————————————————————

动态规划思想,分别取上左下右四个方向,但注意不要超过边界
class Solution(object):
    def updateMatrix(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: List[List[int]]
        """
        row = len(matrix)
        col =  len(matrix[0])
        for i in range(row):
            for j in range(col):
                if matrix[i][j] == 1:
                    matrix[i][j] = row + col
                if i > 0:
                    matrix[i][j] = min([matrix[i][j], matrix[i-1][j]+1])
                if j > 0:
                    matrix[i][j] = min([matrix[i][j], matrix[i][j-1]+1])
        for i in range(row - 1,-1,-1):
            for j in range(col - 1,-1,-1):
                if i < row - 1:
                    matrix[i][j] = min([matrix[i][j], matrix[i+1][j]+1])
                if j < col - 1:
                    matrix[i][j] = min([matrix[i][j], matrix[i][j+1]+1])
        return matrix

在这里插入图片描述

BFS遍历所有情况
class Solution(object):
    def updateMatrix(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: List[List[int]]
        """
        self.m = len(matrix)
        self.n = len(matrix[0])
        res = [[0 for j in range(self.n)] for i in range(self.m)]
        for i in range(self.m):
            for j in range(self.n):
                res[i][j] = self.distance(i,j,0,matrix,[])
        return res
    def distance(self,i,j,step,matrix,que):
        que.append((i,j,step))
        while que:
            temp = que.pop(0)
            if matrix[temp[0]][temp[1]] == 0:
                return temp[2]
            if temp[0]>0:
                que.append((temp[0]-1,temp[1],temp[2]+1))
            if temp[1]>0:
                que.append((temp[0],temp[1]-1,temp[2]+1))
            if temp[0]<self.m-1:
                que.append((temp[0]+1,temp[1],temp[2]+1))
            if temp[1]<self.n-1:
                que.append((temp[0],temp[1]+1,temp[2]+1))

在这里插入图片描述

2.钥匙和房间

有 N 个房间,开始时你位于 0 号房间。每个房间有不同的号码:0,1,2,…,N-1,并且房间里可能有一些钥匙能使你进入下一个房间。

在形式上,对于每个房间 i 都有一个钥匙列表 rooms[i],每个钥匙 rooms[i][j] 由 [0,1,…,N-1] 中的一个整数表示,其中 N = rooms.length。 钥匙 rooms[i][j] = v 可以打开编号为 v 的房间。

最初,除 0 号房间外的其余所有房间都被锁住。

你可以自由地在房间之间来回走动。

如果能进入每个房间返回 true,否则返回 false。

示例 1:
输入: [[1],[2],[3],[]]
输出: true
解释:
我们从 0 号房间开始,拿到钥匙 1。
之后我们去 1 号房间,拿到钥匙 2。
然后我们去 2 号房间,拿到钥匙 3。
最后我们去了 3 号房间。
由于我们能够进入每个房间,我们返回 true。

示例 2:
输入:[[1,3],[3,0,1],[2],[0]]
输出:false
解释:我们不能进入 2 号房间。

提示:
1 <= rooms.length <= 1000
0 <= rooms[i].length <= 1000
所有房间中的钥匙数量总计不超过 3000。
—————————————————————————————————————————

类似于广度优先,遍历所有可以去的房间
class Solution(object):
    def canVisitAllRooms(self, rooms):
        """
        :type rooms: List[List[int]]
        :rtype: bool
        """
        room = [0]
        visited = [0]
        for i in rooms[0]:
            room.append(i)
        while set(visited) != set(room):
            for i in room:
                if i not in visited:
                    for j in rooms[i]:
                        room.append(j)
                    visited.append(i)
        return len(visited) == len(rooms)

在这里插入图片描述

同样的广度优先,区别在于可以将房间的开闭用0与1代替,减少时间
class Solution(object):
    def canVisitAllRooms(self, rooms):
        """
        :type rooms: List[List[int]]
        :rtype: bool
        """
        n = len(rooms)
        mark = [0 for _ in range(n)]
        mark[0] = 1 #0号已开
        stack = [0]
        while stack:
            now = stack.pop()
            for roomkey in rooms[now]:
                if not mark[roomkey]:
                    stack.append(roomkey)
                    mark[roomkey] = 1 #已开
        return sum(mark) == n

在这里插入图片描述

3.寻找数组的中心索引

给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法。

我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和。

如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。

示例 1:
输入:
nums = [1, 7, 3, 6, 5, 6]
输出: 3
解释:
索引3 (nums[3] = 6) 的左侧数之和(1 + 7 + 3 = 11),与右侧数之和(5 + 6 = 11)相等。
同时, 3 也是第一个符合要求的中心索引。

示例 2:
输入:
nums = [1, 2, 3]
输出: -1
解释:
数组中不存在满足此条件的中心索引。

说明:
nums 的长度范围为 [0, 10000]。
任何一个 nums[i] 将会是一个范围在 [-1000, 1000]的整数。
—————————————————————————————————————————

既然需要左右相等,那么就可以通过从前向后找到原数组和的一半的数组
class Solution(object):
    def pivotIndex(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) in [0,2]:
            return -1
        if len(nums) == 1:
            return 0
        sums = sum(nums)
        add = 0.0
        for i in range(len(nums)):
            if add + float(nums[i]) / 2 == float(sums) / 2:
                return i
            else:
                add += nums[i]
        return -1

在这里插入图片描述

4.至少是其他数字两倍的最大数

在一个给定的数组nums中,总是存在一个最大元素 。

查找数组中的最大元素是否至少是数组中每个其他数字的两倍。

如果是,则返回最大元素的索引,否则返回-1。

示例 1:
输入: nums = [3, 6, 1, 0]
输出: 1
解释: 6是最大的整数, 对于数组中的其他整数,
6大于数组中其他元素的两倍。6的索引是1, 所以我们返回1.

示例 2:
输入: nums = [1, 2, 3, 4]
输出: -1
解释: 4没有超过3的两倍大, 所以我们返回 -1.

提示:
nums 的长度范围在[1, 50].
每个 nums[i] 的整数范围在 [0, 99].
—————————————————————————————————————————

很简单的思路,直接判断最大数值是否是第二大数值的二倍
class Solution(object):
    def dominantIndex(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) == 1:
            return 0
        number_max = max(nums)
        index = nums.index(number_max)
        nums.pop(index)
        number_2max = max(nums)
        if number_max >= 2 * number_2max:
            return index
        return -1

在这里插入图片描述
以上就是今日经验!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值