zoukankan      html  css  js  c++  java
  • leetcode刷题(三)

    1、图论

    找到小镇的法官

    在一个小镇里,按从 1 到 N 标记了 N 个人。传言称,这些人中有一个是小镇上的秘密法官。

    如果小镇的法官真的存在,那么:

    小镇的法官不相信任何人。
    每个人(除了小镇法官外)都信任小镇的法官。
    只有一个人同时满足属性 1 和属性 2 。
    给定数组 trust,该数组由信任对 trust[i] = [a, b] 组成,表示标记为 a 的人信任标记为 b 的人。

    如果小镇存在秘密法官并且可以确定他的身份,请返回该法官的标记。否则,返回 -1。

    示例 1:

    输入:N = 2, trust = [[1,2]]
    输出:2
    示例 2:

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

    输入:N = 3, trust = [[1,3],[2,3],[3,1]]
    输出:-1
    示例 4:

    输入:N = 3, trust = [[1,2],[2,3]]
    输出:-1
    示例 5:

    输入:N = 4, trust = [[1,3],[1,4],[2,3],[2,4],[4,3]]
    输出:3

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/find-the-town-judge

    class Solution(object):
        def findJudge(self, N, trust):
            """
            :type N: int
            :type trust: List[List[int]]
            :rtype: int
            """
            if not trust:
                if N == 0:
                    return -1
                elif N == 1:
                    return 1
                else:
                    return -1
            
            believe_dict = collections.defaultdict(list)
            believed_dict = collections.defaultdict(list)
            max_count = 0
            result_id = -1
            for p1, p2 in trust:
                believe_dict[p2].append(p1)
                believed_dict[p1].append(p2)
    
            for i in range(1, N + 1):
                if max_count < len(believe_dict[i]):
                    max_count = len(believe_dict[i])
                    result_id = i
    
            if max_count == N - 1 and not believed_dict.get(result_id):
                return result_id
    
            return -1
    

    2、图的遍历

    岛屿的最大面积

    给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合。你可以假设二维矩阵的四个边缘都被水包围着。

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

    示例 1:

    [[0,0,1,0,0,0,0,1,0,0,0,0,0],
    [0,0,0,0,0,0,0,1,1,1,0,0,0],
    [0,1,1,0,1,0,0,0,0,0,0,0,0],
    [0,1,0,0,1,1,0,0,1,0,1,0,0],
    [0,1,0,0,1,1,0,0,1,1,1,0,0],
    [0,0,0,0,0,0,0,0,0,0,1,0,0],
    [0,0,0,0,0,0,0,1,1,1,0,0,0],
    [0,0,0,0,0,0,0,1,1,0,0,0,0]]
    对于上面这个给定矩阵应返回 6。注意答案不应该是11,因为岛屿只能包含水平或垂直的四个方向的‘1’。

    示例 2:

    [[0,0,0,0,0,0,0,0]]
    对于上面这个给定的矩阵, 返回 0。

    注意: 给定的矩阵grid 的长度和宽度都不超过 50。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/max-area-of-island

    class Solution(object):
        def maxAreaOfIsland(self, grid):
            """
            :type grid: List[List[int]]
            :rtype: int
            """
            if not grid:
                return
    
            def solution_by_bfs():
                max_area = 0
                
                def bfs(x, y, grid):
                    queue = [(x, y)]
                    sums = 0
                    while queue:
                        new_queue = []
                        for i, j in queue:
                            if grid[i][j] != 1:
                                continue
                            grid[i][j] = 0
                            sums += 1
                            for next_i, next_j in [(i + 1, j), (i, j + 1), (i - 1, j), (i, j - 1)]:
                                if 0 <= next_i < len(grid) and 0 <= next_j < len(grid[0]) and grid[next_i][next_j] == 1:
                                    new_queue.append((next_i, next_j))
                        queue = new_queue
                    return sums
    
                for i in range(len(grid)):
                    for j in range(len(grid[0])):
                        if grid[i][j] == 1:
                            max_area = max(max_area, bfs(i, j, grid))
                return max_area
    
            def solution_by_dfs(grid):
                max_area = 0
        
                def dfs(i, j, sum, grid):
                    if 0 <= i < len(grid) and 0 <= j < len(grid[0]) and grid[i][j] == 1:
                        grid[i][j] = 0
                        sum[0] += 1
                        dfs(i, j - 1, sum, grid)
                        dfs(i, j + 1, sum, grid)
                        dfs(i - 1, j, sum, grid)
                        dfs(i + 1, j, sum, grid)
    
                for i in range(len(grid)):
                    for j in range(len(grid[0])):
                        sum = [0]
                        dfs(i, j, sum, grid)
                        max_area = max(max_area, sum[0])
                return max_area
            
            # return solution_by_dfs(grid)
            return solution_by_bfs(grid)
    

    3、图的最短路径

    访问所有节点的最短路径

    给出 graph 为有 N 个节点(编号为 0, 1, 2, ..., N-1)的无向连通图。 

    graph.length = N,且只有节点 i 和 j 连通时,j != i 在列表 graph[i] 中恰好出现一次。

    返回能够访问所有节点的最短路径的长度。你可以在任一节点开始和停止,也可以多次重访节点,并且可以重用边。

    示例 1:

    输入:[[1,2,3],[0],[0],[0]]
    输出:4
    解释:一个可能的路径为 [1,0,2,0,3]
    示例 2:

    输入:[[1],[0,2,4],[1,3,4],[2],[1,2]]
    输出:4
    解释:一个可能的路径为 [0,1,4,2,3]

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/shortest-path-visiting-all-nodes

    class Solution(object):
        def shortestPathLength(self, graph):
            """
            :type graph: List[List[int]]
            :rtype: int
            """
            n = len(graph)
            lelvel = 0
            target = (1 << n) - 1
            queue = [(i, 1 << i) for i in range(n)]
            dist = set()
            while queue:
                new_queue = []
                for node, state in queue:
                    if state == target:
                        return lelvel
                    for next_node in graph[node]:
                        new_state = state | (1 << next_node)
                        if (next_node, new_state) not in dist:
                            dist.add((next_node, new_state))
                            new_queue.append((next_node, new_state))
                queue = new_queue
                lelvel += 1
    
            return lelvel
    

    4、图的搜索

    朋友圈

    班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。

    给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。

    示例 1:

    输入:
    [[1,1,0],
    [1,1,0],
    [0,0,1]]
    输出: 2
    说明:已知学生0和学生1互为朋友,他们在一个朋友圈。
    第2个学生自己在一个朋友圈。所以返回2。
    示例 2:

    输入:
    [[1,1,0],
    [1,1,1],
    [0,1,1]]
    输出: 1
    说明:已知学生0和学生1互为朋友,学生1和学生2互为朋友,所以学生0和学生2也是朋友,所以他们三个在一个朋友圈,返回1。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/friend-circles

    class Solution(object):
        def findCircleNum(self, M):
            """
            :type M: List[List[int]]
            :rtype: int
            """
            def dfs(M, visited, i):
                for j in range(len(M)):
                    if M[i][j] == 1 and visited[j] == 0:
                        visited[j] = 1;
                        dfs(M, visited, j)
    
    #         visited = [0 for x in range(len(M))]  # 行搜索
    #         count = 0
    #         for i in range(len(M)):
    #             if visited[i] == 0:
    #                 dfs(M, visited, i);
    #                 count += 1
            
    #         return count
    
            def bfs(M):
                queue = set()
                visited = [0]*len(M)  # 行搜索
                count = 0
                for i in range(len(M)):
                    if visited[i] == 1:
                        continue
                    queue.add(i)
                    while queue:
                        new_queue = set()
                        for s in queue:
                            visited[s] = 1
                            for j in range(len(M)):
                                if M[s][j] == 1 and visited[j] == 0:
                                    new_queue.add(j)
                        queue = new_queue
                    count += 1
                return count
            return bfs(M)
            
            def find_num(M):  # 并查集
                def find(parent, i):
                    if parent[i] == -1:
                        return i
                    return find(parent, parent[i])
    
                def union(parent, x, y) :
                    xset = find(parent, x)
                    yset = find(parent, y)
                    if xset != yset:
                        parent[xset] = yset
    
                parent = [-1 for x in range(len(M))]
                for i in range(len(M)):
                    for j in range(len(M)):
                        if M[i][j] == 1 and i != j:
                            union(parent, i, j)
    
                count = 0
                print(parent)
                for i in range(len(parent)):
                    if parent[i] == -1:
                        count += 1
                return count
            # return find_num(M)
    

      

  • 相关阅读:
    iOS: 学习笔记, Swift与C指针交互(译)
    kubernetes多节点部署的决心
    vim温馨提示
    简单工厂
    C++调用一个成员函数的需求this指针的情况
    hdoj 1226 超级password 【隐图BFS】
    Oracle Global Finanicals Technical Reference(一个)
    连载:面向对象的葵花宝典:思维、技能与实践(40)
    Android启动第三方应用程序
    BZOJ 1004 HNOI2008 Cards Burnside引理
  • 原文地址:https://www.cnblogs.com/rnanprince/p/12217155.html
Copyright © 2011-2022 走看看