leetcode每日一题 21-30

21)999. 车的可用捕获量

leetcode链接:https://leetcode-cn.com/problems/available-captures-for-rook/

代码

'''
方法1:
找到R所在位置并记录
将R所在行/列含有的R/B/p分别记录在两个数组中
如果数组中R相邻的元素为p则加1
最后得到答案
'''
class Solution(object):
    def numRookCaptures(self, board):
        """
        :type board: List[List[str]]
        :rtype: int
        """
        x,y=0,0
        for i in range(8):
            for j in range(8):
                if board[i][j]=='R':
                    x,y=i,j
                    break
        lis1 = []
        lis2 = []
        for i in range(8):
            if board[x][i]!='.':
                lis1.append(board[x][i])
            if board[i][y]!='.':
                lis2.append(board[i][y])
        ans = 0
        for i in range(len(lis1)):
            if lis1[i]=='R':
                y=i
                break
        for i in range(len(lis2)):
            if lis2[i]=='R':
                x=i
                break
        if 0<=y-1<len(lis1) and lis1[y-1]=='p':
            ans+=1
        if 0<=y+1<len(lis1) and lis1[y+1]=='p':
            ans+=1
        if 0<=x-1<len(lis2) and lis2[x-1]=='p':
            ans+=1
        if 0<=x+1<len(lis2) and lis2[x+1]=='p':
            ans+=1
        return ans

'''
参考官方题解:
用两个数组记录移动上下左右的方向
'''
class Solution(object):
    def numRookCaptures(self, board):
        """
        :type board: List[List[str]]
        :rtype: int
        """
        x,y=[1,0,-1,0],[0,1,0,-1]
        ans = 0
        r,c=0,0
        for i in range(8):
            for j in range(8):
                if board[i][j]=='R':
                    r,c=i,j
        for i in range(4):
            step = 1
            while True:
                xx=r+x[i]*step
                yy=c+y[i]*step
                if xx<0 or xx>=8 or yy<0 or yy>=8 or board[xx][yy]=='B':
                    break
                elif board[xx][yy]=='p':
                    ans+=1
                    break
                step+=1
        return ans

思考

  • 在数组中求对应数据的下标:循环
  • 关于某个位置和上下、左右数据的关系:循环
  • 好了,这个题就考了个循环

官方题解要比我的简洁很多,和上个题一样,需要注意的点是:如果题目涉及上下左右的移动/迭代,可以用两个数组记录移动的方向,再进行循环,这样写起来代码会简介很多!

22) 914. 卡牌分组

在这里插入图片描述

代码

'''
方法一:
遍历
题目要求:1.每组都有X张牌且为相同的整数
那么X应该小于等于个数最少的牌的数量key_min
从2开始遍历到key_min,如果对于某一个数,能被所有牌数量整除,则返回True
如果遍历完所有的牌仍然没有则返回False
'''
from fractions import gcd
class Solution(object):
    def hasGroupsSizeX(self, deck):
        """
        :type deck: List[int]
        :rtype: bool
        """
        memo = collections.Counter(deck)
        key_min = min(memo.values())
        if key_min<2:
            return False
        for i in range(2,key_min+1):
            k=0
            for j in memo.values():
                if j%i!=0:
                    break
                k+=1
                if k==len(memo):
                    return True
        return False

'''
方法2:
所有元素的最大公约数大于2
'''
from fractions import gcd
class Solution(object):
    def hasGroupsSizeX(self, deck):
        """
        :type deck: List[int]
        :rtype: bool
        """
        memo = collections.Counter(deck).values()
        return reduce(gcd,memo)>=2

思路

  • 暴力枚举
  • 数学:公约数

23)820. 单词的压缩编码

在这里插入图片描述

代码

'''
思路:
用set进行去重
对于一个单词,如果它的后缀也在列表中,则将其删除
'''
class Solution(object):
    def minimumLengthEncoding(self, words):
        """
        :type words: List[str]
        :rtype: int
        """
        good = set(words)
        for word in words:
            for j in range(1,len(word)):
                good.discard(word[j:])
        return sum(len(w)+1 for w in good)

参考:https://leetcode-cn.com/problems/short-encoding-of-words/solution/dan-ci-de-ya-suo-bian-ma-by-leetcode-solution/

思路

  • 遍历后缀,删除与后缀相同的值
  • 字典树

24) 1162. 地图分析

leetcode链接:https://leetcode-cn.com/problems/as-far-from-land-as-possible/
在这里插入图片描述

思路

  • 最远/最近距离–广度优先搜索
  • 这个题思路和橘子腐烂相似,可以用多源广度优先搜索

代码

class Solution(object):
    def maxDistance(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        stack = []
        #使用一个stack记录所有的陆地节点
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j]==1:
                    stack.append((i,j))
        lgrid=len(grid)  
        #如果全为陆地或者海洋则返回-1      
        if len(stack)==0 or len(stack)==lgrid*lgrid:
            return -1
        locs = [[0,1],[0,-1],[1,0],[-1,0]]
        depth=-1
        #广度优先搜索
        while stack:
            depth +=1  #记录距离
            length =len(stack)
            for k in range(length): #多源的一层遍历完再遍历下一层
                i,j = stack.pop(0)
                for loc in locs:
                    ii=i+loc[0]
                    jj=j+loc[1]
                    if 0<=ii<len(grid) and 0<=jj<len(grid[0]) and grid[ii][jj]==0:
                        grid[ii][jj]=2#将已经访问过的海洋置2,避免重复访问
                        stack.append((ii,jj))
        return depth
发布了15 篇原创文章 · 获赞 1 · 访问量 671
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览