lc-649題。佇列模擬題
阿新 • • 發佈:2020-12-12
技術標籤:刷題總結
link
首先是一道簡單的貪心做法,每次投票敵對陣容的下一個就要投票的議員。想到了有序表用來模擬投票過程,彈出一個大於等於現在的這個議員對立陣營的最近的一個議員,投票使得他失去權力。時間複雜度應該可以做到是O(NlogN)的做法,提交的程式碼因為有了for迴圈,時間複雜度應該更高點。
public String predictPartyVictory(String senate) {
char[] s = senate.toCharArray();
int n = s.length;
TreeSet<Integer> r = new TreeSet<>(), d = new TreeSet<>();
for(int i = 0; i < n; i++) {
if(s[i] == 'R') r.add(i);
else d.add(i);
}
while(!r.isEmpty() && !d.isEmpty()) {
for(int i = 0; i < n; i++) {
if(s[i] == 'R') {
if (d.isEmpty()) return "Radiant";
if(!r.contains(i)) continue;
else{
if(d.ceiling(i) != null) d.remove(d.ceiling(i));
else d.remove(d.ceiling(i - n));
}
}else{
if (r.isEmpty()) return "Dire";
if(!d.contains(i)) continue;
else{
if(r.ceiling(i) != null) r.remove(r.ceiling(i));
else r.remove(r.ceiling(i-n));
}
}
}
}
return r.isEmpty() ? "Dire" : "Radiant";
}
當然最優的做法是用佇列模擬就可以了,兩個佇列裡存的是投票的權利的優先順序,最低則越優先,一開始就是各自的索引值,每次投票結束需要加n也就是總人數,再進入佇列,一次彈出兩個議員,優先順序高的投票否認了優先順序低的,優先順序高的+n,再加入自己所在的佇列,直到有一個佇列為空,結束,由於每次操作都會彈出1個議員,所以時間複雜度O(N),空間O(N)
public String predictPartyVictory(String senate) {
char[] s = senate.toCharArray();
int n = s.length;
Queue<Integer> r = new LinkedList<>(), d = new LinkedList<>();
for(int i = 0; i < n; i++) {
if(s[i] == 'R') r.add(i);
else d.add(i);
}
while(!r.isEmpty() && !d.isEmpty()) {
int R = r.poll(), D = d.poll();
if(R < D) r.add(R + n);
else d.add(D + n);
}
return r.isEmpty() ? "Dire" : "Radiant";
}