classSolution { public: vector<int> survivedRobotsHealths(vector<int> &positions, vector<int> &healths, string directions){ int n = positions.size(), id[n]; iota(id, id + n, 0); sort(id, id + n, [&](constint i, constint j) { return positions[i] < positions[j]; });
stack<int> st; for (int i: id) { if (directions[i] == 'R') { // 向右,存入栈中 st.push(i); continue; } // 向左,与栈中向右的机器人碰撞 while (!st.empty()) { int top = st.top(); if (healths[top] > healths[i]) { // 栈顶的健康度大 healths[top]--; healths[i] = 0; break; } if (healths[top] == healths[i]) { // 健康度一样大 healths[top] = 0; st.pop(); // 移除栈顶 healths[i] = 0; break; } healths[top] = 0; st.pop(); // 移除栈顶 healths[i]--; // 当前机器人的健康度大 } }
funcsurvivedRobotsHealths(positions, healths []int, directions string) []int { type data struct { i, p, h int d byte } a := make([]data, len(positions)) for i, p := range positions { a[i] = data{i, p, healths[i], directions[i]} } sort.Slice(a, func(i, j int)bool { return a[i].p < a[j].p })
var toLeft, st []data next: for _, p := range a { if p.d == 'R' { // 向右,存入栈中 st = append(st, p) continue } // p 向左,与栈中向右的机器人碰撞 forlen(st) > 0 { top := &st[len(st)-1] if top.h > p.h { // 栈顶的健康度大 top.h-- continue next } if top.h == p.h { // 健康度一样大 st = st[:len(st)-1] continue next } p.h-- // p 的健康度大 st = st[:len(st)-1] // 移除栈顶 } toLeft = append(toLeft, p) // p 把栈中的全部撞掉 }
// 合并剩余的机器人,按编号排序 toLeft = append(toLeft, st...) sort.Slice(toLeft, func(i, j int)bool { return toLeft[i].i < toLeft[j].i }) ans := make([]int, len(toLeft)) for i, p := range toLeft { ans[i] = p.h } return ans }
复杂度分析
时间复杂度:\mathcal{O}(n\log n),其中 n 为 positions 的长度。瓶颈在排序上。