【区间处理】——差分
适用于【区间修改,单点查询】
差分原题,
概述题意:
给定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】

浙公网安备 33010602011771号