leetcode day13 825,835,870,873,891,900

242 阅读2分钟

825. Friends Of Appropriate Ages

二分查找,注意要判断查找区间是否包含解

835. Image Overlap

谜一样的题,建议搜题解

870. Advantage Shuffle

题意:重排数组A,使得A[i] > B[i]的个数最多

思路:贪心,将B从小到大排序,每个B[i]尝试用最小的A[i]去针对

873. Length of Longest Fibonacci Subsequence

题意:给你一列数,找出最长斐波那契子序列

思路:n只有1000,n^2穷举前两项即可,因为斐波那契数列在10^9以内项数不会很多

891. Sum of Subsequence Widths

题意:给你一列数,对每个子序列,令width = 序列中最大值 - 序列中最小值,求这列数所有子序列的width之和

题解:首先结果显然和这列数的排列顺序无关,因此先把列数排序,那么每个子序列的width就是这个子序列的“最后一个数 - 第一个数”,因此只要枚举子序列的头(i)和尾(j),中间j - i - 1个数有2^(j - i - 1)种取法,这2^(j - i - 1)个子序列的width都等于A[j] - A[i]

答案可以写成:

∑(i=0, n-2)∑(j=i+1, n-1) (A[j] - A[i]) * 2^(j - i - 1)

= ∑(i=0, n-2) 2^-(i+1)∑(j=i+1, n-1)A[j]*2^j -

∑(i=0, n-2)A[i]*2^-(i+1)∑(j=i+1, n-1)2^j

可以用两个数组分别记下p[i]=∑(j=i, n-1)A[j]*2^j 和 p2[i]= ∑(j=i, n-1)2^j

这样在o(N)复杂度下就能求出答案

代码:

class Solution {
public:
    int modn = 1e9 + 7;
    int quickpower(long long b, int x)
    {
        long long s = 1;
        while(x)
        {
            if(x & 1)
                s = s * b % modn;
            b = b * b % modn;
            x >>= 1;
        }
        return s;
    }
    int sumSubseqWidths(vector<int>& A) {
        sort(A.begin(), A.end());
        int n = A.size();
        vector<int> p(n + 5);
        vector<int> p2(n + 5);
        for(int i = n - 1; i >= 0; i--)
        {
            int t = 1ll * A[i] * quickpower(2, i) % modn;
            p[i] = (t + p[i + 1]) % modn;
            int tt = 1ll * quickpower(2, i) % modn;
            p2[i] = (tt + p2[i + 1]) % modn;
        }
        int s1 = 0, s2 = 0;
        for(int i = 0; i < n - 1; i++)
        {
            int t = 1ll * quickpower(quickpower(2, i + 1), modn - 2) * p[i + 1] % modn;
            s1 = (s1 + t) % modn;
            int tt = 1ll * A[i] * quickpower(quickpower(2, i + 1), modn - 2) % modn * p2[i + 1] % modn;
            s2 = (s2 + tt) % modn;
        } cout<<s1<<' '<<s2<<endl;
        return ((s1 - s2) % modn + modn) % modn;
    }
};

900. RLE Iterator

裸二分