leetcode 907, 915, 918, 926, 945,950

547 阅读2分钟

907 Sum of Subarray Minimums

对每个A[i], 找出左边第一个小于它的数,右边小于等于它的第一个数,可以用单调栈实现 ,注意对相等数的处理,一定是一边取小于一边取小于等于

class Solution {
public:
    int modn = 1e9 + 7;
    long long ml[30005], mr[30005];
    int sumSubarrayMins(vector<int>& A) {
        int n = A.size();
        stack<pair<int, int>> stl, str;
        stl.push(make_pair(-1e9, -1));
        for(int i = 0; i < n; i++)
        {
            while(A[i] < stl.top().first)
                stl.pop();
            ml[i] = i - stl.top().second;
            stl.push(make_pair(A[i], i));
        }
        str.push(make_pair(-1e9, n));
        for(int i = n - 1; i >= 0; i--)
        {
            while(A[i] <= str.top().first)
                str.pop();
            mr[i] = str.top().second - i;
            str.push(make_pair(A[i], i));
        }
        long long ans = 0;
        for(int i = 0; i < n; i++)
        { cout << ml[i] <<' '<< mr[i]<<endl;
            ans = (ans + A[i] * ml[i] % modn * mr[i] % modn) % modn;
        }
        return ans;
    }
};

915 Partition Array into Disjoint Intervals

水题不说了

918 Maximum Sum Circular Subarray

求出最大子段和,最小子段和,比较最大子段和总和 - 最小子段和,取其中的较大值;有一种特殊情况是全是负数,需要特殊处理

class Solution {
public:
    int maxSubarraySumCircular(vector<int>& A) {
        int n = A.size();
        long long sum = 0;
        for(int i = 0; i < n; i++)
            sum += A[i];
        long long maxs = -1e9, mins = 1e9, s = 0;
        for(int i = 0; i < n; i++)
        {
            s += A[i];
            maxs = max(maxs, s);
            if(s <= 0)
                s = 0;
        }
        s = 0;
        for(int i = 0; i < n; i++)
        {
            s += A[i];
            mins = min(mins, s);
            if(s >= 0)
                s = 0;
        } //cout<< sum << ' ' << mins <<' '<< maxs<<endl;
        if(mins == sum)
            return maxs;
        return max(maxs, sum - mins);
    }
};

926 Flip String to Monotone Increasing

也是水题

945 Minimum Increment to Make Array Unique

先排序,然后确保A[i] >= A[i - 1] + 1就行了

class Solution {
public:
    int minIncrementForUnique(vector<int>& A) {
        sort(A.begin(), A.end());
        int n = A.size();
        int ans = 0;
        for(int i = 1; i < n; i++)
        {
            if(A[i] <= A[i - 1])
            {
                ans += A[i - 1] - A[i] + 1;
                A[i] = A[i - 1] + 1;
            }
        }
        return ans;
    }
};

950 Reveal Cards In Increasing Order

链表模拟吧

class Solution {
public:
    struct Link
    {
        int id;
        struct Link* next;
        Link(int x)
        {
            id = x;
            next = nullptr;
        }
    };
    vector<int> deckRevealedIncreasing(vector<int>& deck) {
        sort(deck.begin(), deck.end());
        int n = deck.size();
        Link* head, *tail;
        for(int i = 0; i < n; i++)
        {
            Link *node = new Link(i);
            if(i == 0)
                head = tail = node;
            else
            {
                tail -> next = node;
                tail = node;
            } 
        }
        vector<int> ans(n);
        int i = 0;
        while(true)
        {
            ans[head -> id] = deck[i++]; 
            if(head -> next != nullptr)
            {
                head = head -> next;
                tail -> next = head;
                tail = head;
                head = head -> next;
                tail -> next = nullptr;
            }
            else
                break;
        }
        return ans;
    }
};