สมมติว่าในกลุ่มสังคม มี N คนที่แตกต่างกัน โดยมีรหัสจำนวนเต็มที่ไม่ซ้ำกันตั้งแต่ 0 ถึง N-1 ที่นี่ เรามีรายการบันทึก โดยแต่ละ logs[i] =[time, id_A, id_B] มีการประทับเวลาของจำนวนเต็มไม่เป็นลบ และรหัสของคนสองคนที่แตกต่างกัน บันทึกแต่ละรายการจะแสดงเวลาที่คนสองคนกลายเป็นเพื่อนกัน ถ้า A เป็นเพื่อนกับ B แล้ว B คือเพื่อนกับ A สมมุติว่า A สนิทกับ B ถ้า A เป็นเพื่อนกับ B หรือ A เป็นเพื่อนของคนที่รู้จัก B เราต้องหาเวลาให้เร็วที่สุด ที่ทุกคนคุ้นเคยกันดี หากไม่พบเวลาดังกล่าว ให้คืนค่า -1 ดังนั้นหากอินพุตมีลักษณะดังนี้:[[20190101,0,1], [20190104,3,4], [20190107,2,3], [20190211,1,5] , [20190224,2,4], [20190301,0,3], [20190312,1,2], [20190322,4,5]], N =6, ผลลัพธ์จะเป็น 20190301 เนื่องจากเหตุการณ์แรกเกิดขึ้น ที่ประทับเวลา =20190101 และหลังจากที่บุคคลที่ 0 และ 1 กลายเป็นเพื่อนกัน เราก็มีกลุ่มมิตรภาพ [0,1], [2], [3], [4], [5] จากนั้นเหตุการณ์ที่สองจะเกิดขึ้นที่ timestamp =20190104 และหลังจากที่บุคคลที่ 3 และ 4 กลายเป็นเพื่อนกัน เรามีกลุ่มมิตรภาพดังต่อไปนี้ [0,1], [2], [3,4], [5] หลังจากนั้นเหตุการณ์ที่สามจะเกิดขึ้นที่เวลาประทับ =20190107 และหลังจากที่บุคคลที่ 2 และ 3 กลายเป็นเพื่อนกัน เรามีกลุ่มมิตรภาพดังต่อไปนี้ [0,1], [2,3,4], [5] จากนั้นเหตุการณ์ที่สี่เกิดขึ้นที่ timestamp =20190211 และหลังจากที่บุคคลที่ 1 และ 5 กลายเป็นเพื่อนกัน เรามีกลุ่มมิตรภาพดังต่อไปนี้ [0,1,5], [2,3,4] หลังจากเหตุการณ์ที่ 5 เกิดขึ้น ณ เวลาประทับ =20190224 และเนื่องจากบุคคลที่ 2 และ 4 เป็นเพื่อนกันแล้ว อะไรก็เกิดขึ้นได้ สุดท้าย เหตุการณ์ที่หกเกิดขึ้นที่ timestamp =20190301 และหลังจากที่บุคคลที่ 0 และ 3 กลายเป็นเพื่อนกัน เราก็กลายเป็นเพื่อนกัน
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
กำหนดวิธีการที่เรียกว่า find() ซึ่งจะใช้ค่า x ซึ่งจะทำงานดังนี้ −
-
ถ้า parent[x] คือ -1 ให้คืนค่า x
-
พ่อแม่[x] :=find(parents[x])
-
ส่งคืนผู้ปกครอง[x]
-
โดยวิธีการหลักจะทำงานดังนี้ −
-
กำหนดอาร์เรย์สองอาร์เรย์ที่เรียกว่าพาเรนต์และอันดับ ขนาด N เติมพาเรนต์ด้วย -1 และเติมอันดับด้วย 1 วินาที
-
จัดเรียงบันทึก
-
สำหรับแต่ละองค์ประกอบ i ในบันทึก -
-
ดำเนินการสหภาพบน i[1] และ i[2]
-
find(i[2]) และ find(i[1])
-
ถ้า N อยู่ในอาร์เรย์อันดับ ให้ส่งคืน i[0]
-
-
กลับ -1
ตัวอย่าง(C++)
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int earliestAcq(vector<vector<int>>& logs, int N) {
vector<int> ds (N, -1);
sort(begin(logs), end(logs));
for(vector<int> &k : logs) {
if(un(k[1], k[2], ds) == N) return k[0];
}
return -1;
}
int un(int u, int v, vector<int> & ds) {
u = find(u, ds);
v = find(v, ds);
if(u != v) {
ds[v] += ds[u];
ds[u] = v;
}
return -ds[v];
}
int find(int u, vector<int> & ds) {
return ds[u] < 0? u : ds[u] = find(ds[u], ds);
}
};
main(){
vector<vector<int>> v = {
{20190101,0,1},{20190104,3,4},{20190107,2,3},{20190211,1,5},
{20190224,2,4},{20190301,0,3},{20190312,1,2},{20190322,4,5}
};
Solution ob;
cout <<ob.earliestAcq(v, 6);
} อินพุต
[[20190101,0,1],[20190104,3,4],[20190107,2,3],[20190211,1,5], [20190224,2,4],[20190301,0,3],[20190312,1,2],[20190322,4,5]] 6
ผลลัพธ์
20190301