leetcode刷题 —— 16.04 井字游戏与python中*和**的使用总结

 

一、原题

 

二、解法

   1、个人思路

        看到这道题目后没有想到什么简单有效的方法,于是直接暴力求解:依次处理每一行、每一列以及两条对角线上的字符即可,代码如下:
class Solution(object):
    def tictactoe(self, board):
        """
        :type board: List[str]
        :rtype: str
        """
        N = len(board[0])
        # 处理每一行
        for i in range(N):
            for j in range(1, N):
                if board[i][j] != board[i][0]:
                    break
            else:
                if board[i][0] != " ":
                    return board[i][0]
         # 处理每一列
        for i in range(N):
            for j in range(1, N):
                if board[j][i] != board[0][i]:
                    break
            else:
                if board[0][i] != " ":
                    return board[0][i]
        #  主对角线
        for i in range(1, N):
            if board[i][i] != board[0][0]:
                break
        else:
            if board[0][0] != " ":
                return board[0][0]

        # 副对角线
        for i in range(1, N):
            if board[i][N-1-i] != board[0][N-1]:
                break
        else:
            if board[0][N-1] != " ":
                return board[0][N-1]
        # 判断棋盘上是否还有空位
        for val in board:
            if val.find(" ") != -1:
                return "Pending"
        return "Draw"

 

 
 
      意外的是,没想到如此“朴素”的解法在内存消耗和用时上表现还比较好。

    2、题解中他人思路

      (1) any()函数

 
        在python中,函数any()接收一个可迭代的参数iter,若iter中的元素都为False,则any()函数返回False;若至少有一个元素为True,则any()函数返回True。元素除了0、“”(空)或者False时 都看作为True。
     
print(any([1, 0, 5]))             # True
print(any([0, 0, 0]))             # False
print(any([False, False, True]))  # True
print(any(("", "a", "")))         # True
print(any(("", "" ,"")))          # False
print(any([]))                    # Flase

   (2)python中*的使用情况总结

       a、作为乘号
 
print(5*8)     # 输出40

       b、*号后面的数字表示重复的次数

 
print([0, 'c']*3)   # [0, 'c', 0, 'c', 0, 'c']

      c、调用函数时实参前加*

        如下代码中我们定义了函数test,test会接收三个实参;同时定义了一个有三个元素的列表a,若我们想将a中的元素作为实参传给test,可直接执行test(*a)。
        即若将*放于可迭代的变量(List、元组、字典等)前,则它会将变量中的值依次取出。
 
def test(a, b, c):
    pass

a = [1, 2, 3]
test(*a)    #  等价于test(a[0], a[1], a[2])

    d、定义函数时,形参前加*

 
def test(a, b, *args):
    print(a)
    print(b)
    print(args)
    print(type(args))

test(1, 2, 3, 4, 5)

       代码执行的结果为:

 
1
2
(3, 4, 5)
<class 'tuple'>

        分析可知,执行test(1, 2, 3, 4, 5)以后,将1赋给了形参a,2赋给了形参b,而剩下的实参3、4、5三个数则一起赋给了形参args,且args的类型是一个元组。因此,在定义函数时,若形参前加*,则我们可以将该形参理解为一个元组。

 

  (3)、python中**的的使用情况总结

      a、可将" a**n"理解为求a的n次方
 
print(5**3)    # 125

     b、定义函数时形参前使用**

 
def test(**args):
    print(type(args))
    print(args)

test(a=1, b=2, c=3)

        代码的执行结果为:


<class 'dict'>
{'a': 1, 'b': 2, 'c': 3}
        可知,若在形参前使用**,则说明这个形参是一个字典
     c、实参前使用**
 
def test(a, b, c):
    print(a)
    print(b)
    print(c)

dict = {a:1, b:2, c:3}
test(**dict)

         执行代码,输出为:

1
2
3

   (4)zip()函数

        python3中,该函数接收可迭代的对象作为参数,将各个对象中的元素打包成一个个元组,并返回由这些元组组成的对象。
 
a = [1, 2, 3]
b = [4, 5, 6]
zipped = zip(a, b)
# print(tuple(zipped))  #将zipped转换为元组输出
print(list(zipped))   #将zipped转换为列表输出

       执行代码,结果为:


[(1, 4), (2, 5), (3, 6)]
       有了以上基础,我们可以理解以下代码了:
    def tictactoe(self, board: List[str]) -> str:
        N = len(board[0])
        def exist(c):
            string = c * N
            return any((
                # 处理行
                any(string == line for line in board),
                # 处理列
                any(string == col for col in map(''.join, zip(*board))),
                # 处理主对角线
                all(c == board[i][i] for i in range(N)),
                # 处理副对角线
                all(c == board[i][N-1-i] for i in range(N))
            )
            )
        if exist("O") == True:
            return "O"
        if exist("X") == True:
            return "X"
      #  for line in board:
      #     if line.find(" ") != -1:
      #        return "Pending"
        if " " in "".join(board):
            return "Pending"
        return "Draw"

 

 
 
 
 
 
 
      
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值