1. 程式人生 > 其它 >649. Dota2 參議院

649. Dota2 參議院

技術標籤:leetcode

第一次嘗試 暴力

本來想統計字串裡面R和D的數目,發現想得太簡單了

“DDRRR”

雖然R多,但卻是D贏了,因為D先行ban了兩個R,還剩一個R ban了一個D,然後剩下那個D又把R給ban了,最後5個只剩下一個D所以是D贏

第二次嘗試 模擬

觀察上面的投票過程,只有當佇列中能夠投票的元素均相同的時候才能宣佈勝利,否則每個元素都會禁止離它最近的下一個敵對元素,那麼我們按照這個策略來模擬

  1. 使用r和d來統計當前分別能夠投票的元素個數,使用flag陣列標記flag[i]是否有投票權利
  2. 遍歷佇列,直到r或d為0,執行以下操作
  3. 從當前元素開始尋找最近的敵對元素,修改其flag[i]=false
  4. 返回不為0的元素
class Solution:
    def predictPartyVictory(self, senate: str) -> str:
        size = len(senate)
        r,d = 0,0
        for ch in senate:
            if ch == 'R':
                r+=1
            else:
                d+=1
        flag = [True] * size
        ind = 0
        while r!=0 and
d!=0: if flag[ind]: ch = senate[ind] j = (ind+1)%size while True: if ch == 'R' and senate[j] == 'D' and flag[j] == True: d-=1 break if ch == 'D' and senate[
j] == 'R' and flag[j] == True: r-=1 break j = (j+1)%size flag[j] = False ind = (ind+1)%size # print(flag) if r!=0: return 'Radiant' else: return 'Dire'

在這裡插入圖片描述
通過了,但是效率很低,主要是往後找元素這個過程花費時間太長了

改進

我們只遍歷一輪,用r和d來表示當前擁有投票權的元素

  1. 如果當前元素是R,並且d==0,那麼r+=1,反之同理
  2. 如果當前元素是R,但是d!=0,那麼不做任何操作,反之同理
  3. 遍歷一輪後檢查r和d的數量

但是我們每個元素在一輪決策中只能投票一次,所以上面的遍歷還要改進,我們現在用兩個佇列r和d來儲存可以投票的元素

  1. 如果當前元素是R,d佇列為空,那麼入隊r佇列,否則d隊列出隊一個元素,儲存到res字串中等待下一輪投票,反之同理
  2. 取出res字串中的元素,重複上述遍歷
  3. 如果res為空,那麼我們檢查佇列元素,返回相應答案
class Solution:
    def predictPartyVictory(self, senate: str) -> str:
        size = len(senate)
        r,d = [],[] 
        res = senate 
        while res!='':
            senate = res
            res = ''
            for ch in senate:
                if ch=='R':
                    if len(d)==0:
                        r.append('R') 
                    else:
                        res+=d.pop()
                else:
                    if len(r)==0:
                        d.append('D')
                    else:
                        res+=r.pop()
                        
        if len(r)!=0:
            return 'Radiant'
        else:
            return 'Dire'     

在這裡插入圖片描述
這次效率高了很多