zoukankan      html  css  js  c++  java
  • 【Leetcode】搜索相关

    【Leetcode-127】

    一、题目:单词接龙

      字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列:

      序列中第一个单词是 beginWord 。
      序列中最后一个单词是 endWord 。
      每次转换只能改变一个字母。
      转换过程中的中间单词必须是字典 wordList 中的单词。
      给你两个单词 beginWord 和 endWord 和一个字典 wordList ,找到从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0。

      1 <= beginWord.length <= 10

      endWord.length == beginWord.length

      1 <= wordList.length <= 5000
      wordList[i].length == beginWord.length
      beginWord、endWord 和 wordList[i] 由小写英文字母组成
      beginWord != endWord
      wordList 中的所有字符串 互不相同

    二、代码:

    def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
            """
            求最短序列,即广度搜索,邻接节点预先产生需要任2个word计算是否邻接,复杂度最高5000*5000*10,为节省空间和时间,计算过程中计算邻接单词
            """
            import copy
            def generate(word, word_set):
                res = []
                for i, char in enumerate(word):  # 换每个字符
                    for j in range(26):
                        trans_char = chr(ord('a') + j)  # 换成该字符
                        if char == trans_char:
                            continue
                        word[i] = trans_char
                        if ''.join(word) in word_set:
                            res.append(copy.deepcopy(word))
                        word[i] = char
                return res
                        
            word_set = set(wordList)  # 用于计算邻接单词时判断某单词是否是需要的
            if endWord not in word_set:
                return 0
            word_cnt = len(wordList)
            visited = set()  # 避免形成闭环
            que = [list(beginWord)]
            visited.add(beginWord)
            level = 0
            while len(que) > 0:
                level += 1
                for _ in range(len(que)):
                    node = que.pop(0)
                    if ''.join(node) == endWord:
                        return level
                    neibor_list = generate(node, word_set)
                    for neibor in neibor_list:
                        neibor_str = ''.join(neibor)
                        if neibor_str not in visited:
                            que.append(neibor)
                            visited.add(neibor_str)
            return 0

    【Leetcode-130】

    一、题目:被围绕的区域

      给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X'围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。

    二、代码:

    def solve(self, board: List[List[str]]) -> None:
            """
            题目要求为:把不与边界相连的连通域改成X,与边界相连的不改
            做法:从边界出发找连通域,找到的做标记(改成#),最后把未做标记的O改成X
            """
            m, n = len(board), len(board[0])
            neibor_list = [[1, 0], [-1, 0], [0, 1], [0, -1]]
            def dfs(i, j):
                board[i][j] = '#'  # 被遍历了
                for neibor in neibor_list:
                    new_i, new_j = i+neibor[0], j+neibor[1]
                    if 0<=new_i<=m-1 and 0<=new_j<=n-1 and board[new_i][new_j] == 'O':
                        dfs(new_i, new_j)
            
            # 边缘出发找连通域
            for i in range(m):
                for j in range(n):
                    if i == 0 or j==0 or i==m-1 or j==n-1:
                        if board[i][j] == 'O':
                            dfs(i, j)
            # 后处理
            for i in range(m):
                for j in range(n):
                    if board[i][j] == '#':
                        board[i][j] = 'O'
                    elif board[i][j] == 'O':
                        board[i][j] = 'X'

    【Leetcode-200】

    一、题目:岛屿数量

      给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

      岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

      此外,你可以假设该网格的四条边均被水包围。

    二、代码:

    """
    代码1
    """
    def numIslands(self, grid: List[List[str]]) -> int:
            neibors = [[1, 0], [-1, 0], [0, 1], [0, -1]]
            m, n = len(grid), len(grid[0])
            merged = [[False]*n for _ in range(m)]
            def dfs(i, j):
                merged[i][j] = True
                for x, y in neibors:
                    new_x, new_y = x+i, y+j
                    if 0 <= new_x < m and 0 <= new_y < n and not merged[new_x][new_y] and grid[new_x][new_y] == "1":
                        dfs(new_x, new_y)
    
            num = 0
            for i in range(m):
                for j in range(n):
                    if not merged[i][j] and grid[i][j] == "1":
                        num += 1
                        dfs(i, j)
            return num
    """
    代码2
    """
    def numIslands(self, grid: List[List[str]]) -> int:
            neibors = [[1, 0], [-1, 0], [0, 1], [0, -1]]
            m, n = len(grid), len(grid[0])
            merged = [[False]*n for _ in range(m)]
    
            num = 0
            for i in range(m):
                for j in range(n):
                    if not merged[i][j] and grid[i][j] == "1":
                        num += 1
                        que = []
                        merged[i][j] = True
                        que.append((i, j))
                        while len(que) > 0:
                            node = que.pop()
                            for x, y in neibors:
                                new_x, new_y = node[0]+x, node[1]+y
                                if 0 <= new_x < m and 0 <= new_y < n and not merged[new_x][new_y] and grid[new_x][new_y] == "1":
                                    merged[new_x][new_y] = True
                                    que.append((new_x, new_y))
    
            return num

    【Leetcode-207】

    一、题目:

      你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。

      在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程  bi 。

      例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
      请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false。

    二、代码:

    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: 
            # 按出度入度表计算,把入度为0的结点放入,填充依赖它的项,全部节点出栈表示完成
            visted = set()
            in_degree = [0]*numCourses  # 表示依赖的结点个数
            out_degree_list = [[] for i in range(numCourses)]  # 可支撑的结点
            for a, b in prerequisites:  # a依赖b,b支撑a
                in_degree[a] += 1
                out_degree_list[b].append(a)
            # 把无依赖的结点加入队列
            que = [i for i, cnt in enumerate(in_degree) if cnt == 0]
            while len(que) > 0:
                node = que.pop(0)
                visted.add(node)  # 已经解决的结点
                # 尝试填充被依赖的结点
                for item in out_degree_list[node]:
                    in_degree[item] -= 1
                    if in_degree[item] == 0:  # 全部依赖都满足
                        visted.add(item)
                        que.append(item)
    
            if len(visted) == numCourses:
                return True
            else:
                return False

     【Leetcode-399】

    一、题目:除法求值

      给你一个变量对数组 equations 和一个实数值数组 values 作为已知条件,其中 equations[i] = [Ai, Bi] 和 values[i] 共同表示等式 Ai / Bi = values[i] 。每个 Ai 或 Bi 是一个表示单个变量的字符串。

      另有一些以数组 queries 表示的问题,其中 queries[j] = [Cj, Dj] 表示第 j 个问题,请你根据已知条件找出 Cj / Dj = ? 的结果作为答案。

      返回 所有问题的答案 。如果存在某个无法确定的答案,则用 -1.0 替代这个答案。如果问题中出现了给定的已知条件中没有出现的字符串,也需要用 -1.0 替代这个答案。

      注意:输入总是有效的。你可以假设除法运算中不会出现除数为 0 的情况,且不存在任何矛盾的结果。

    二、代码:

     def calcEquation(self, equations: List[List[str]], values: List[float], queries: List[List[str]]) -> List[float]:
            """
            dfs
            """
            # 定义dfs
            def dfs(root, val, query):
                if root == query:
                    return True, val
                visited.add(root)
                neibor_list = map_neibor[root]
                for neibor, v in neibor_list:
                    if neibor not in visited:
                        flag, final_v = dfs(neibor, val*v, query)
                        if flag:
                            return flag, final_v
                return False, None
    
            map_neibor = {}
            all_char = set()
            #  转换成临接表
            for i in range(len(equations)):
                c1, c2 = equations[i]
                v = values[i]
                map_neibor.setdefault(c1, []).append((c2, v))
                map_neibor.setdefault(c2, []).append((c1, 1/v))
                all_char.add(c1)
                all_char.add(c2)
    
            # 调用
            res = []
            for item in queries:
                visited = set()
                x, y = item
                if x in all_char and y in all_char:
                    if x == y:
                        res.append(1)
                    else:
                        flag, v = dfs(x, 1, y)
                        if flag:
                            res.append(v)
                        else:
                            res.append(-1)
                else:
                    res.append(-1)
            return res

    【Leetcode-695】

    一、题目:岛屿的最大面积

      给定一个包含了一些 0 和 1 的非空二维数组 grid 。

      一个 岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在水平或者竖直方向上相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

      找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为 0 。)

    二、代码:

    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
            """
            dfs
            """
            m, n = len(grid), len(grid[0])
            visted = [[0] * n for _ in range(m)]
            neibors = [[1, 0], [-1, 0], [0, 1], [0, -1]]
            def dfs(pre_sum, i, j):  
                """
                输入为:前面传过来的和,要遍历的位置,返回遍历完该位置获得的和
                """
                visted[i][j] = 1
                pre_sum += 1
                for neibor in neibors:
                    new_i, new_j = i + neibor[0], j + neibor[1]
                    if 0 <= new_i < m and 0 <= new_j < n and grid[new_i][new_j] == 1 and not visted[new_i][new_j]:
                        pre_sum += dfs(0, new_i, new_j)
                return pre_sum
                
            max_res = 0
            for i in range(m):
                for j in range(n):
                    if grid[i][j] == 1 and not visted[i][j]:
                        max_res = max(max_res, dfs(0, i, j))
    
            return max_res
    博文转载请注明出处。
  • 相关阅读:
    NSArray & NSDictionary
    copy&mutableCopy 浅拷贝(shallow copy)深拷贝 (deep copy)
    03-图形上下文栈, 图形的平移 旋转 缩放
    02- 画文字和图片-------------之前写的那个微博项目,可以试试用画图片的方式来处理,这样应该比UILabel 代码少点,一会试试
    Quartz 官网翻译(转载)
    01 画简单线的方法
    @property 修饰符
    SEL 类型
    Java 常用快捷键
    Java判断是否为数字
  • 原文地址:https://www.cnblogs.com/EstherLjy/p/14617879.html
Copyright © 2011-2022 走看看