1. 程式人生 > 其它 >列舉、包裝類、Math等實用類

列舉、包裝類、Math等實用類

技術標籤:leetcode演算法C++

隨手筆記:

這篇文章聊一下做leetcode題庫:1128.等價多米諾骨牌對的數量這道題。題目可以點選連結檢視,程式碼也很簡單,解題思路也很簡單,這裡介紹下作為一個演算法新手通過做這道題的一些收穫。

這道題的簡單舉例就是[1,2]和[2,1]相等,計算出現相等的數量。題目採用很巧妙的一個思想,因為題目中說【x,y】中,x,y均大於等於1,小於等於9,所以可以將這個包含兩個數的陣列當成一個二位數(從11-99)來看,比如將【1,2】看做是12,【3,6】看做是36,怎麼判斷x,y調換順序後相等呢,方法就是用小的數做十位,大的數做各位。這樣就可以推出以下的關係:

  1. 當x<y時,value=10*x+y;
  2. 當x>=y時,value=10*y+x;

另一個非常巧妙的地方是對於相等的數量的計算。因為整數是從11-99,所以可以用一個包含100個整數的陣列,下標表示這個【x,y】的value,存放的值是value出現的數量,對於一個數組nums【i】,一開始存放0,表示其出現次數為0。

對於【1,2】、【1,2】、【2,1】、【2,1】出現4次,我們認為有6對相等,$C_4^2$,即3+2+1+0。推廣一下:對於出現n次的【x,y】,相等的對數為$C_n^2$,即(n-1)+(n-2)+····+2+1+0,ret的計算就是巧妙的利用了這種方式來計算相等對數的。

對於某一個【x,y】,先計算value,ret先加上出現的次數減一,即更新前的陣列nums中存放的值,然後在更新當前出現的次數,即更新nums【value】的值。

Leetcode可通過程式碼(C++):

class Solution {
public:
    int numEquivDominoPairs(vector<vector<int>>& dominoes) {

        //建立陣列來計算重複的個數
        vector<int> nums(100);
        int ret=0;
        for(auto & it : dominoes)
        {
            int value= it[0]<it[1]? 10*it[0]+it[1] : 10*it[1]+it[0];
            ret+=nums[value];   //計算相等個數 n-1 + n-2 +····+2+1+0;
            nums[value]++;      //更新計數,表示多出現一次重複
        }

        return ret;
    }
};

謹以此篇來記錄刷題學到的一些演算法巧妙之處。有不懂的可以留言給我,博主看到會認真回覆的。