【区间处理】——差分

适用于【区间修改,单点查询】

差分原题

概述题意:

给定0<=num[i]<num.size的数组,求有效元素(i>=num[i])最多的轮换次数k(有效元素数量相同则取最小k)。

我的分析:

  1.暴力处理,但是O(n^2)时间复杂度过高,

  2.滑动窗口,每轮对有效值记录,无效值入缓存,每次只需要对缓存和当前序号i和i-n+1处理(想法不是很完善就没写)

  3.由于是区间修改,我就想到了树状数组,实际上也确实能解决,但是我当时写不出来阿!!!

如上,没法子了。

然后看题解发现是差分or滑动窗口。。。

analysis:

  找到方法后,现在就是处理区间修改的问题:

  假定当前下标为i,轮动次数为k,那么轮动后下标为i-k

  i-k范围[nums[i],n-1]->k的范围是[i-(n-1),i-nums[i]]

  统一处理一下下标合法:(x+n)%n即可。

代码:

class Solution
{
public:
    vector<int> platesBetweenCandles(string s, vector<vector<int>> &queries)
    {
        int sum = 0, len1 = s.length(), len2 = queries.size(), l, r;
        vector<int> num(len1), left(len1), right(len1), ans;
        for (int i = 0, l = len1 - i - 1, r = i; i < len1; ++i)
        {
            if (s[i] == '|')
                num[i] = ++sum, r = i;
            if (s[len1 - i - 1] == '|')
                l = i;
            right[i] = r;           //右侧的边界蜡烛下标
            left[len1 - i - 1] = l; //左侧边界蜡烛下标
        }
        for (int i = 0; i < len2; ++i)
        {
            l = queries[i][0], r = queries[i][1];
            l = right[l], r = left[r];
            cout << "l==" << l << ", r==" << r << endl;
            ans.emplace_back((r >= l) ? r - l - (num[r] - num[l]) : 0);
        }
        return ans;
    }
};
差分处理

【Over】

posted @ 2022-03-10 18:46  Renhr  阅读(87)  评论(0)    收藏  举报