LeetCode 128周賽

1. 題目列表

2. 十進制整數的反碼

簡單進制轉換。

代碼:

class Solution {
public:
    int bitwiseComplement(int N) {
        if (N == 0) return 1;
        vector<int> bits;
        while (N){
            bits.push_back(N % 2);
            N /= 2;
        }
        for (int i = 0; i < bits.size(); i++)
            bits[i] = bits[i] ? 0 : 1;
        int res = 0, base = 1;
        for (int i = 0; i < bits.size(); i++){
            res += bits[i] * base;
            base *= 2;
        }
        return res;
    }
};

3. 總持續時間可被 60 整除的歌曲

先用hashtable記錄每個整數出現的次數,再用set記錄所有的不重復整數。
遍歷set,對于元素e,枚舉e ~ 500所有的整數i,判斷(e + i)是否能被60整除,如果能整除,計算整數對數。

整數對數的討論:
當e == i,對數 = C(n,2), n為元素e出現的次數
當e != i,對數 = C(n1,1) + C(n2,1),n1和n2分別為e和i出現的次數。

代碼:

class Solution {
public:
    int numPairsDivisibleBy60(vector<int>& time) {
        int hashtable[510];
        unordered_set<int> t;
        memset(hashtable, 0, sizeof(hashtable));
        for (int i = 0; i < time.size(); i++){
            hashtable[time[i]]++;
            t.insert(time[i]);
        }
        int res = 0;
        unordered_set<int>::iterator iter;
        for (iter = t.begin(); iter != t.end(); iter++){
            int e = *iter;
            for (int i = e; i <= 500; i++){
                if ((e + i) % 60 == 0){
                    if (i == e)
                        res += (hashtable[i] * (hashtable[i] - 1)) / 2;
                    else
                        res += hashtable[i] * hashtable[e];
                }
            }
        }
        return res;
    }
};

4. 在 D 天內送達包裹的能力

二分搜索 + 貪心模擬:

要有敏銳的嗅覺,輸出答案存在明顯的范圍,很有可能可用二分查找。

二分查找的關鍵是:如何尋找貪心策略。本題的貪心是盡可能在D天內使得船的載重量最小,船的載重范圍[max(weights), sum(weights)]

這樣,思路很明了,給定船的當前載重為mid,判斷能否在D天內裝滿所有的貨物,如果能,則搜索[l,mid],否則搜索[mid + 1, r]

代碼:

class Solution {
public:
    int shipWithinDays(vector<int>& weights, int D) {
        int sum = 0, MAX = -1;
        for (int i = 0; i < weights.size(); i++){
            sum += weights[i];
            MAX = max(MAX, weights[i]);
        }
        int l = MAX, r = sum, mid;
        while (l < r){
            mid = (l + r) / 2;
            int temp = 0, days = 1;
            for (int i = 0; i < weights.size(); i++){
                temp += weights[i];
                if (temp > mid){
                    days++;
                    temp = weights[i];
                }
            }
            if (days <= D){
                r = mid;
            }else l = mid + 1;
        }
        return r;
    }
};

5. 至少有 1 位重復的數字

排列組合:
注意轉換思路,當討論重復位過于復雜時,轉換問題為計算1~N的不重復位數有多少個。

具體步驟:
假設N的位數為p,先計算1~p-1位的不重復位的個數。如97783,p = 5,設位數為i
i = 1時, 共9種
i = 2時, 共9 * 9 = 81種
i = 3時, 共9 * 9 * 8種
i = 4時, 共9 * 9 * 8 * 7種
i = 5時, 需要逐位討論,設討論的當前位為j
j = 1時,計算第一位小于N[1]的個數,_ _ _ _ _ 共8 * 9 * 8 * 7 * 6種
j = 2時,計算第二位小于N[2]的個數,9_ _ _ _ _ 共 7 * 8 * 7 * 6種,
j = 3時,計算第三位小于N[3]的個數,97_ _ _ 共7 * 7 * 6種,
j = 4時,計算第四位小于N[4]的個數,977_ _ _,此時出現重復位,則不用計算剩下的位數。
res = N - sum
注意:特判N < 10,return 0

代碼:

class Solution {
public:
    int numDupDigitsAtMostN(int N) {
        if (N < 10) return 0;
        int a = N; // 拷貝N
        int p = 0;
        vector<int> digits;
        while (N){
            p++;
            digits.push_back(N % 10);
            N /= 10;
        }
        int sum = 0;
        for (int i = 1; i < p; i++){
            int cnt = 9;
            for (int j = 1; j < i; j++)
                cnt = cnt * (10 - j);
            sum += cnt;
        }
        reverse(digits.begin(), digits.end());
        int len = digits.size();
        int hash[11];
        memset(hash, 0, sizeof(hash));
        for (int i = 0; i < len; i++){
            int cnt = 0;
            if (i == 0){
                cnt = digits[i] - 1;
                hash[digits[i]] = 1;
                if (cnt <= 0) continue;
                for (int j = 1; j <= len - 1; j++)
                    cnt *= (10 - j);
                sum += cnt;
            }else if(i == len - 1){
                for (int j = 0; j <= digits[i]; j++){
                    if (!hash[j]) cnt++;
                }
                sum += cnt;
            }else{
                int cf = 0; // 定義當前位與前導位重復位的個數
                for (int j = 0; j < digits[i]; j++){
                    if (hash[j]) cf++;
                }
                cnt = digits[i] - cf; // 當前位的可選個數 = 0 ~ (digits[i] - 1) - 重復位個數 
                for (int j = i + 1; j < len; j++){
                    cnt *= (10 - j); // 剩余位可選擇的個數
                }
                sum += cnt;
                if (hash[digits[i]] == 1){ // 如果當前位與前導位存在重復位,那么后續位不存在滿足條件的數
                    break;
                }
                hash[digits[i]] = 1; // 記錄當前位已存在
            }
        }
        return a - sum;
    }
};
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容