leetcode 1042. 不鄰接植花(圖 - k染色問題 待研究)

【題目】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]

提示:
1 <= N <= 10000
0 <= paths.size <= 20000
不存在花園有 4 條或者更多路徑可以進入或離開。
保證存在答案。

【解題思路1】圖 - k染色問題

1、根據paths建立鄰接表;
2、默認所有的花園先不染色,即染0;
3、從第一個花園開始走,把與它鄰接的花園的顏色從color{1,2,3,4}這個顏色集中刪除;
4、刪完了所有與它相鄰的顏色,就可以把集合中剩下的顏色隨機選一個給它了,爲了簡單,將集合中的第一個顏色賦給當前花園;
5、循環3和4到最後一個花園。

過程:

  • 存儲鄰接點信息
  • 遍歷所有節點,對於每個節點
  • 查看其鄰接點顏色,使用不同的顏色染色即可
//Map
class Solution {
    public int[] gardenNoAdj(int N, int[][] paths) {
        /* 這是一道簡單題,限制每個節點的度爲3,同時提供四種顏色,因此不需要回溯 */
        /* 初始化節點,使用map保存節點與其臨界點的關係 */
        /* 第一版本採用了內部類構建,參考評論區的HashMap更簡潔 */
        Map<Integer, Set<Integer>> graph = new HashMap<>();
        for (int i = 0; i < N; i++) {
            graph.put(i, new HashSet<>());
        }
        /* 初始化路徑信息 */
        for (int[] path: paths) {
            int a = path[0] - 1;
            int b = path[1] - 1;
            graph.get(a).add(b);
            graph.get(b).add(a);
        }
        int[] res = new int[N];
        for (int i = 0; i < N; i++) {
            boolean[] used = new boolean[5];
            /* 查看當前節點的所有鄰接點的色彩 */
            for (int adj: graph.get(i)) {
                used[res[adj]] = true;
            }
            /* 爲當前節點染色 */
            for (int j = 1; j <= 4; j++) {
                if (!used[j]) {
                    res[i] = j;
                }
            }
        }
        return res;
    }
}
//數組
class Solution {
    public int[] gardenNoAdj(int N, int[][] paths) {
        int[][] topo = new int[N+1][3] ;
        for( int[] cur : paths ){
            int temp = 0 ;
            while( topo[cur[0]][temp] != 0 ) temp++ ;
            topo[cur[0]][temp] = cur[1] ;
            temp = 0 ;
            while( topo[cur[1]][temp] != 0 ) temp++ ;
            topo[cur[1]][temp] = cur[0] ;
        }
        int[] res1 = new int[N+1] ;
        int[] res = new int[N] ;
        for( int i = 1 ; i <= N ; i++ ){
            int temp = 1 ;
            while( res1[topo[i][0]] == temp || res1[topo[i][1]] == temp || res1[topo[i][2]] == temp ) temp++ ;
            res1[i] = temp ;
        }
        for( int i = 0 ; i < N ; i++ ) res[i] = res1[i+1] ;
        return res ;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章