這是悅樂書的第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-1
(arr2[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+篇,公衆號對話框回覆【數據結構與算法】、【算法】、【數據結構】中的任一關鍵詞,獲取系列文章合集。
以上就是全部內容,如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支持!