1. 程式人生 > 其它 >LeetCode大部分是medium難度不怎麼按順序題解(下)

LeetCode大部分是medium難度不怎麼按順序題解(下)

ATP又想買新遊戲了,但硬盤裡放不下了。難過。

前言

但是就沒辦法,平時也沒啥理由整天刷題,真到了要面試的時候手感沒了還就是得刷leetcode找手感。
就不像以前搞OI的時候每天就只管刷題,手感如何都不會丟。
所以我還在刷leetcode。我的老天爺,想想現在找工作要刷leetcode,以後萬一想跳槽了還得刷leetcode。
可能哪一天網際網路泡沫破滅了我回家開奶茶店了就不用刷leetcode了。
leetcode我(嗶————)

正文

322. 零錢兌換

簡單DP。因為amount的範圍很小所以直接開陣列就行了。
注意最後判斷無解。答案最大是amount(若干個面值為1的拼起來),所以只要把INF設定為大於amount的值就行了。

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        int f[10010], n = coins.size();
        memset(f, 127, sizeof(f));
        f[0] = 0;
        for (int i = 1; i <= amount; i ++)
            for (int j = 0; j < n; j ++)
                if (coins[j] <= i)
                    f[i] = min(f[i], f[i - coins[j]] + 1);
        if (f[amount] <= amount)
            return f[amount];
        else return -1;
    }
};

324. 擺動排序

首先有一個結論:有解的陣列必定可以分成“較大”和“較小”兩部分,滿足“較大”部分的最小數大於等於“較小”部分的最大數,且兩部分的數字個數最多相差1。
證明這個結論很簡單。首先構造一個初始序列:因為一定有解,所以把解的偶數位置上的數字放一堆,奇數位置的放一堆。
顯然奇數部分是“較小”的,偶數部分是“較大”的。
如果這樣的兩個序列不滿足要求,那麼“較大”那部分的最小數肯定小於“較小”那部分的最大數。這兩個數交換一下位置,兩個部分數字的個數沒變。重複這種操作最後一定能滿足要求。
所以只要把這兩部分分開就可以了。

能O(n)時間做出來的關鍵就在於數組裡每個數字不大於5000。這樣就可以用桶排序的思路做。
我的做法用了O(n)的額外空間。基本思路就是先桶排序,然後把較大的一半放在奇數位,較小的一半放在偶數位。
具體實現裡面我首先讓奇數位的序列遞增,偶數位的序列遞減。但這樣做出來最後可能有相等的相鄰數字(比如樣例2)
所以最後再掃一遍把偶數位的序列倒過來就可以了。

class Solution {
public:
    void wiggleSort(vector<int>& nums) {
        int cnt[50010], mx = 0, n = nums.size();
        for (int i = 0; i < n; i ++) {
            cnt[nums[i]] ++;
            mx = max(mx, nums[i]);
        }
        int p1 = 0, p2 = mx;
        nums.clear();
        while (p1 <= p2) {
            while (p1 <= p2 && cnt[p1] == 0) p1 ++;
            while (p1 <= p2 && cnt[p2] == 0) p2 --;
            if (p1 > p2) break;
            if (cnt[p1] > 0) {
                nums.push_back(p1); cnt[p1] --;
            }
            if (cnt[p2] > 0) {
                nums.push_back(p2); cnt[p2] --;
            }
        }
        p1 = 0; p2 = n - 1;
        if (p2 & 1) p2 --;
        while (p1 <= p2) {
            swap(nums[p1], nums[p2]);
            p1 += 2; p2 -= 2;
        }
    }
};