LeetCode.997-找到鎮法官(Find the Town Judge)

這是悅樂書的第373次更新,第400篇原創

01 看題和準備

今天介紹的是LeetCode算法題中Easy級別的第234題(順位題號是997)。在一個城鎮,有N個人從1到N標記。有傳言說其中一個人是祕密的鎮法官。

如果鎮法官存在,那麼:

  • 鎮法官不信任任何人。

  • 每個人(鎮法官除外)都信任鎮法官。

  • 只有一個人滿足前兩條。

給定一個trust數組,一對trust[i] = [a,b]表示被標記爲a的人信任標記爲b的人。

如果鎮法官存在並且可以識別,則返回鎮法官的標籤。否則,返回-1。

例如:

輸入:N = 2,trust = [[1,2]]
輸出:2

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

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

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

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

注意

  • 1 <= N <= 1000

  • trust.length <= 10000

  • trust[i]都是不同的。

  • trust[i][0] != trust[i][1]

  • 1 <= trust[i][0],trust[i][1] <= N

02 第一種解法

將題目翻譯一下就是,法官的被信任次數等於N-1,並且法官不能信任其他人,即法官是trust數組中trust[i][1]出現次數等於N-1的人(被信任次數等於N-1),並且trust[i][0]不等於法官所在的標籤(法官不能信任其他人)。

思路:利用HashMap記錄被信任人出現的次數,找出其中被信任了N-1次的人,然後去trust數組中判斷此人是否有信任過其他人。有種特殊情況N爲1的時候,trust爲空數組,即只有1個人,那麼這個人就是法官。

public int findJudge(int N, int[][] trust) {
    // 只有1個人的時候,法官就是他本人
    if (N == 1) {
        return N;
    }
    // key爲被信任的人,value爲其被信任的次數
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    for (int[] arr : trust) {
        map.put(arr[1], map.getOrDefault(arr[1], 0)+1);
    }
    // 找到被信任次數等於N-1的那個人
    int count = -1;
    for (Integer key : map.keySet()) {
        if (map.get(key) == N-1) {
            count = key;
        }
    }
    // 被信任次數等於N-1的人,不能信任其他人
    for (int[] arr : trust) {
        if (arr[0] == count) {
            return -1;
        }
    }
    return count;
}


03 第二種解法

針對第一種解法中的HashMap,我們還可以用int數組進行替換,思路和上面第一種解法一致。

public int findJudge2(int N, int[][] trust) {
    if (N == 1) {
        return N;
    }
    int[] trusted = new int[N+1];
    for (int i=0; i<trust.length; i++) {
        trusted[trust[i][1]]++;
    }
    int count = -1;
    for (int i=0; i<trusted.length; i++) {
        if (trusted[i] == N-1) {
            count = i;
        }
    }
    for (int[] arr : trust) {
        if (arr[0] == count) {
            return -1;
        }
    }
    return count;
}


04 第三種解法

針對第二種解法,我們還可以將其簡化成2個for循環,將統計被信任次數和尋找被信任次數最多的人合在一起處理。

public int findJudge3(int N, int[][] trust) {
    if (N == 1) {
        return N;
    }
    int[] trusted = new int[N+1];
    int count = -1, num = -1;
    for (int i=0; i<trust.length; i++) {
        trusted[trust[i][1]]++;
        if (trusted[trust[i][1]] > count) {
            count = trusted[trust[i][1]];
            num = trust[i][1];
        }
    }
    // 被信任次數要等於N-1
    if (count != N-1) {
        return -1;
    }
    for (int[] arr : trust) {
        if (arr[0] == num) {
            return -1;
        }
    }
    return num;
}


05 第四種解法

我們還可以使用兩個int數組來解,一個數組arr存信任的人,另一個數組arr2存被信任的人,找出被信任次數等於N-1arr2[i]=N-1)且沒有信任過人(arr[i]=0)的人,他就是法官。

public int findJudge4(int N, int[][] trust) {
    int[] arr = new int[N+1];
    int[] arr2 = new int[N+1];
    for (int i=0; i<trust.length; i++) {
        arr[trust[i][0]]++;
        arr2[trust[i][1]]++;
    }
    for (int j=1; j<arr.length; j++) {
        if (arr[j] == 0 && arr2[j] == N-1) {
            return j;
        }
    }
    return -1;
}


06 小結

算法專題目前已連續日更超過七個月,算法題文章240+篇,公衆號對話框回覆【數據結構與算法】、【算法】、【數據結構】中的任一關鍵詞,獲取系列文章合集。

以上就是全部內容,如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支持!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章