LeetCode50天刷题计划(Day 43 —子集(20)单词搜索(40)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

没啥想说的 六级不能考了 我心如死灰

一、题目

子集

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例

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

示例 2:
输入:nums = [0]
输出:[[],[0]]

提示

1 <= nums.length <= 10
-10 <= nums[i] <= 10
nums 中的所有元素 互不相同

二、思路

找到求子集的规律即可(首先的想法是化成子问题)
全集每增加一个元素,其子集个数就变为原来的两倍,也就是在原先每个子集中添加新的元素,形成另一半新的子集
实现使用列表生成式~

三、代码

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        #遍历nums,在re_list所有元素后添加i,再加入re_list中成为新元素
        re_list=[[]]
        for i in nums:
            re_list+=[j+[i] for j in re_list]
        return re_list

在这里插入图片描述

四、题目

单词搜索

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例

示例 1:
输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true

示例 2:
输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “SEE”
输出:true

示例 3:
输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCB”
输出:false

提示

m == board.length
n = board[i].length
1 <= m, n <= 6
1 <= word.length <= 15
board 和 word 仅由大小写英文字母组成

五、思路

很明显的深度优先搜索,每次在当前位置考虑四个方向能否前进,然后递归调用函数
①注意需要保证字母不重复使用,引入used矩阵来实现
②代码写完后可以发现,大量的篇幅都用在重复的向上下左右走,因此能否将他们集成一下呢?这样就有了方向向量:
建立directions = [(0, 1), (0, -1), (1, 0), (-1, 0)],这样每次只需要遍历方向向量数组,就可以考虑所有可能的下一步位置!

for di, dj in directions:
    newi, newj = i + di, j + dj

这种方法可以减少写的代码量

六、代码

1.初级

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        #很明显的深度优先搜索,且数据规模并不大,如果需要增大数据规模,就要思考剪枝的方法
        heng=len(board[0])-1 #棋盘横宽
        zong=len(board)-1 #棋盘纵长
        n=len(word) #字符串长度
        flag=[False] #标志位
        used=[[0]* (heng+1) for k in range(zong+1)] #记录用过的,防止重复使用字母!!
        #寻找下一个字母
        def dfs(flag,n,length,i,j):
            if(length==n): #完成条件
                flag[0]=True
                return
            if(flag[0]==True): #终止条件
                return 
            if(j>0 and board[i][j-1]==word[length] and used[i][j-1]==0): #向左
                used[i][j-1]=1
                dfs(flag,n,length+1,i,j-1)
                used[i][j-1]=0
            if(j<heng and board[i][j+1]==word[length] and used[i][j+1]==0): #向右
                used[i][j+1]=1
                dfs(flag,n,length+1,i,j+1)
                used[i][j+1]=0
            if(i>0 and board[i-1][j]==word[length] and used[i-1][j]==0): #向上
                used[i-1][j]=1
                dfs(flag,n,length+1,i-1,j)
                used[i-1][j]=0
            if(i<zong and board[i+1][j]==word[length] and used[i+1][j]==0): #向下
                used[i+1][j]=1
                dfs(flag,n,length+1,i+1,j)
                used[i+1][j]=0
        #首先要寻找到第一个字母
        for i in range(zong+1):
            for j in range(heng+1):
                if(board[i][j]==word[0]): #出发点
                    used[i][j]=1
                    dfs(flag,n,1,i,j)
                    used[i][j]=0
                    if(flag[0]==True): #找到就返回
                        break
            if(flag[0]==True): #找到就返回
                break
        #返回
        return flag[0]
            

在这里插入图片描述

2.加入方向向量

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        #很明显的深度优先搜索,且数据规模并不大,如果需要增大数据规模,就要思考剪枝的方法
        heng=len(board[0])-1 #棋盘横宽
        zong=len(board)-1 #棋盘纵长
        n=len(word) #字符串长度
        flag=[False] #标志位
        used=[[0]* (heng+1) for k in range(zong+1)] #记录用过的,防止重复使用字母!!
        directons=[(0,-1),(0,1),(-1,0),(1,0)] #方向数组
        #寻找下一个字母
        def dfs(flag,n,length,i,j):
            if(length==n): #完成条件
                flag[0]=True
                return
            if(flag[0]==True): #终止条件
                return 
            for a,b in directons:
                tempi,tempj=i+a,j+b
                if(tempi>=0 and tempj>=0 and tempi<=zong and tempj<=heng and board[tempi][tempj]==word[length] and used[tempi][tempj]==0): #整合版
                    used[tempi][tempj]=1
                    dfs(flag,n,length+1,tempi,tempj)
                    used[tempi][tempj]=0
            
        #首先要寻找到第一个字母
        for i in range(zong+1):
            for j in range(heng+1):
                if(board[i][j]==word[0]): #出发点
                    used[i][j]=1
                    dfs(flag,n,1,i,j)
                    used[i][j]=0
                    if(flag[0]==True): #找到就返回
                        break
            if(flag[0]==True): #找到就返回
                break
        #返回
        return flag[0]

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值