1042. 不鄰接植花

有 N 個花園,按從 1 到 N 標記。在每個花園中,你打算種下四種花之一。

paths[i] = [x, y] 描述了花園 x 到花園 y 的雙向路徑。

另外,沒有花園有 3 條以上的路徑可以進入或者離開。

你需要爲每個花園選擇一種花,使得通過路徑相連的任何兩個花園中的花的種類互不相同。

以數組形式返回選擇的方案作爲答案 answer,其中 answer[i] 爲在第 (i+1) 個花園中種植的花的種類。花的種類用 1, 2, 3, 4 表示。保證存在答案。

示例 1:

輸入:N = 3, paths = [[1,2],[2,3],[3,1]]
輸出:[1,2,3]

示例 2:

輸入:N = 4, paths = [[1,2],[3,4]]
輸出:[1,2,1,2]

示例 3:

輸入:N = 4, paths = [[1,2],[2,3],[3,4],[4,1],[1,3],[2,4]]
輸出:[1,2,3,4]
處。

解題思路: 鄰接矩陣(adjacency matrix)是圖ADT最基本的實現方式

代碼如下:

class Solution(object):
    def gardenNoAdj(self, N, paths):
        """
        :type N: int
        :type paths: List[List[int]]
        :rtype: List[int]
        """
        # 思路: 對於當前的某一個花園,剔除掉與它鄰接花園的花的種類,從剩下的種類中選一種即可。
        # 1. 構建鄰接矩陣G; 2. 用res列表保存當前花園花的種類
        res = [0]*N
        G = [[] for _ in range(N)]
        for x, y in paths:
            G[x - 1].append(y - 1)
            G[y - 1].append(x - 1)
        for i in range(N):
            # 對於當前花園, 排除掉鄰接的花園的花種就ok了,然後pop出一種
            res[i] = ({1,2,3,4} - {res[j] for j in G[i]}).pop()
        return res

思路:

  1. 首先用鄰接表path_map構建地圖,這裏採用的是列表中的下表表示花園,列表中的元素還是列表,表示和這個列表相連接的花園。
  2. result存放結果,下標是花園,值是花的種類。
  3. 從花園1開始爲每個花園種花,在當前花園i中,與它相鄰的花園中編號i大的先不用管,該花園還沒有種花;對於編號比i小的花園,需要將他們中的花的種類放到set中,因爲與i相連的花園可能種相同的花。
  4. 最後從1到4開始遍歷,最小的數字j不在set中,那麼花園i就中花j。

代碼如下:

class Solution:
    def gardenNoAdj(self, N: int, paths: List[List[int]]) -> List[int]:
        
        result = [0 for x in range(N+1)]
        path_map = [[] for x in range(N+1)]
        
        #構建地圖
        for num in paths:
            path_map[num[0]].append(num[1])
            path_map[num[1]].append(num[0])
        s = set() #存儲該花園相鄰的花園種植的花
        for i in range(1,N+1):
            s.clear()
            for j in path_map[i]:
                if( j < i):
                    s.add(result[j])
            for j in range(1,5):
                if(j not in s):
                    count = j
                    break
            result[i] = count

        return result[1:]

1043. 分隔數組以得到最大和

給出整數數組 A,將該數組分隔爲長度最多爲 K 的幾個(連續)子數組。分隔完成後,每個子數組的中的值都會變爲該子數組中的最大值。

返回給定數組完成分隔後的最大和。

示例:

輸入:A = [1,15,7,9,2,5,10], K = 3
輸出:84
解釋:A 變爲 [15,15,15,9,10,10,10]

動態規劃:

class Solution(object):
    def maxSumAfterPartitioning(self, A, K):
        """
        :type A: List[int]
        :type K: int
        :rtype: int
        """
        n = len(A)
        curmax = 0
        res = [0 for _ in range(n)]
        for i in range(len(A)):
            if i < K:
                curmax = max(A[i], curmax)
                res[i] = curmax*(i+1)
            else:
                curmax = 0
                for j in range(1, K+1):
                    curmax = max(A[i-j+1], curmax)
                    res[i] = max(res[i], res[i-j]+curmax*j)
        return res[n-1]

997. 找到小鎮的法官

在一個小鎮裏,按從 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

解題思路:

  1. 分別用兩個數組存儲,一個用來存儲入度數,也就是相信你的人的個數,數組下標就是代表該人,1到N
  2. 另外一個用來存儲出度數,也就是你相信的人的個數
  3. 入度數等於N-1,出度數爲0,則這個人就是法官,否則無法確定法官。
class Solution(object):
    def findJudge(self, N, trust):
        """
        :type N: int
        :type trust: List[List[int]]
        :rtype: int
        """
        a=[0 for x in range(N+1)]   #相信你的人
        b=[0 for x in range(N+1)]    #你相信的人
        
        for num in trust:
            a[num[1]]+=1  #儲存爲相信他的人
            b[num[0]] +=1
        
        for i ,num in enumerate(a):
            if(i!=0 and num==N-1):
                if b[i]==0:
                    
                    return i
        return -1

841. 鑰匙和房間

有 N 個房間,開始時你位於 0 號房間。每個房間有不同的號碼:0,1,2,…,N-1,並且房間裏可能有一些鑰匙能使你進入下一個房間。

在形式上,對於每個房間 i 都有一個鑰匙列表 rooms[i],每個鑰匙 rooms[i][j][0,1,...,N-1] 中的一個整數表示,其中 N = rooms.length。 鑰匙 rooms[i][j] = v 可以打開編號爲 v 的房間。

最初,除 0 號房間外的其餘所有房間都被鎖住。

你可以自由地在房間之間來回走動。

如果能進入每個房間返回 true,否則返回 false。

示例 1:

輸入: [[1],[2],[3],[]]
輸出: true
解釋:  
我們從 0 號房間開始,拿到鑰匙 1。
之後我們去 1 號房間,拿到鑰匙 2。
然後我們去 2 號房間,拿到鑰匙 3。
最後我們去了 3 號房間。
由於我們能夠進入每個房間,我們返回 true。

示例 2:

輸入:[[1,3],[3,0,1],[2],[0]]
輸出:false
解釋:我們不能進入 2 號房間。

解題思路:

有向圖的深度優先搜索。
設置兩個數組notVisitedvisited,分別存放還未遍歷過的房間號和已經遍歷過的房間號。如果notVisited數組爲空說明我們已經遍歷過所有房間,直接返回,如果當前房間已經遍歷過了也直接返回。然後遍歷鑰匙串中的房間號。
代碼如下:

代碼如下:

class Solution(object):
    def canVisitAllRooms(self, rooms):
        """
        :type rooms: List[List[int]]
        :rtype: bool
        """
        notVisited = [i for i in range(1, len(rooms))]
        visited = []

        def dfs(curRoom, keys):
            if len(notVisited) == 0:
                return
            if curRoom in visited:
                return
            visited.append(curRoom)
            for key in keys:
                if key in notVisited:
                    notVisited.remove(key)
                dfs(key, rooms[key])

        dfs(0, rooms[0])
        return True if len(notVisited) == 0 else False

802. 找到最終的安全狀態

思路分析:典型的圖深度優先搜索。
dfs訪問圖,當前訪問路徑上節點狀態待定,爲-1:

  1. 訪問完當前路徑,未發現環,則所有節點狀態標記爲1(已訪問節點)。
  2. 發現環,所有節點狀態不變,爲-1(環上節點)。
class Solution(object):
    def eventualSafeNodes(self, graph):
        """
        :type graph: List[List[int]]
        :rtype: List[int]
        """
        nodes_status = [0] * len(graph)
        safe_nodes = []
        for i in range(len(graph)):
            if nodes_status[i] == 0:
                self.dfs(graph, i, nodes_status, safe_nodes)
        return sorted(safe_nodes)

    def dfs(self, graph, i, nodes_status, safe_nodes):
        nodes_status[i] = 1
        flag = False
        for sub_node in graph[i]:
            if nodes_status[sub_node] == 0:
                if self.dfs(graph, sub_node, nodes_status, safe_nodes):
                    flag = True
            elif nodes_status[sub_node] == 1:
                flag = True
        if not flag:
            safe_nodes.append(i)
            nodes_status[i] = 2
        return flag

332. 重新安排行程

class Solution(object):
    def findItinerary(self, tickets):
        """
        :type tickets: List[List[str]]
        :rtype: List[str]
        """
        tickets.sort()
        hel = [False for i in range(len(tickets))]
        def dfs(s,res):
            if len(res)==len(tickets)+1:
                return res
            for i in range(len(tickets)):
                if not hel[i] and tickets[i][0]==s:
                    hel[i] = True
                    r = dfs(tickets[i][1],res+[tickets[i][1]])
                    if not r:
                        hel[i] = False   
                    else:return r
        return dfs('JFK',['JFK'])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章