diff --git a/leetcode/2701-2800/2751.Robot-Collisions/1.png b/leetcode/2701-2800/2751.Robot-Collisions/1.png new file mode 100644 index 000000000..7111feea7 Binary files /dev/null and b/leetcode/2701-2800/2751.Robot-Collisions/1.png differ diff --git a/leetcode/2701-2800/2751.Robot-Collisions/2.png b/leetcode/2701-2800/2751.Robot-Collisions/2.png new file mode 100644 index 000000000..49b92e535 Binary files /dev/null and b/leetcode/2701-2800/2751.Robot-Collisions/2.png differ diff --git a/leetcode/2701-2800/2751.Robot-Collisions/3.png b/leetcode/2701-2800/2751.Robot-Collisions/3.png new file mode 100644 index 000000000..b0ec458e0 Binary files /dev/null and b/leetcode/2701-2800/2751.Robot-Collisions/3.png differ diff --git a/leetcode/2701-2800/2751.Robot-Collisions/README.md b/leetcode/2701-2800/2751.Robot-Collisions/README.md new file mode 100644 index 000000000..e6e9c6fe1 --- /dev/null +++ b/leetcode/2701-2800/2751.Robot-Collisions/README.md @@ -0,0 +1,53 @@ +# [2751. Robot Collisions][title] + +## Description +There are `n` **1-indexed** robots, each having a position on a line, health, and movement direction. + +You are given **0-indexed** integer arrays `positions`, `healths`, and a string `directions` (`directions[i]` is either **'L'** for **left** or **'R'** for **right**). All integers in `positions` are **unique**. + +All robots start moving on the line **simultaneously** at the **same speed** in their given directions. If two robots ever share the same position while moving, they will **collide**. + +If two robots collide, the robot with **lower health** is **removed** from the line, and the health of the other robot **decreases by one**. The surviving robot continues in the **same** direction it was going. If both robots have the **same** health, they are both removed from the line. + +Your task is to determine the **health** of the robots that survive the collisions, in the same **order** that the robots were given, i.e. final heath of robot 1 (if survived), final health of robot 2 (if survived), and so on. If there are no survivors, return an empty array. + +Return an array containing the health of the remaining robots (in the order they were given in the input), after no further collisions can occur. + +**Note**: The positions may be unsorted. + +**Example 1:** + +![1](./1.png) + +``` +Input: positions = [5,4,3,2,1], healths = [2,17,9,15,10], directions = "RRRRR" +Output: [2,17,9,15,10] +Explanation: No collision occurs in this example, since all robots are moving in the same direction. So, the health of the robots in order from the first robot is returned, [2, 17, 9, 15, 10]. +``` + +**Example 2:** + +![2](./2.png) + +``` +Input: positions = [3,5,2,6], healths = [10,10,15,12], directions = "RLRL" +Output: [14] +Explanation: There are 2 collisions in this example. Firstly, robot 1 and robot 2 will collide, and since both have the same health, they will be removed from the line. Next, robot 3 and robot 4 will collide and since robot 4's health is smaller, it gets removed, and robot 3's health becomes 15 - 1 = 14. Only robot 3 remains, so we return [14]. +``` + +**Example 3:** + +![3](./3.png) + +``` +Input: positions = [1,2,5,6], healths = [10,10,11,11], directions = "RLRL" +Output: [] +Explanation: Robot 1 and robot 2 will collide and since both have the same health, they are both removed. Robot 3 and 4 will collide and since both have the same health, they are both removed. So, we return an empty array, []. +``` + +## 结语 + +如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-algorithm][me] + +[title]: https://leetcode.com/problems/robot-collisions +[me]: https://github.com/kylesliu/awesome-golang-algorithm diff --git a/leetcode/2701-2800/2751.Robot-Collisions/Solution.go b/leetcode/2701-2800/2751.Robot-Collisions/Solution.go index d115ccf5e..b1ea8d3bb 100755 --- a/leetcode/2701-2800/2751.Robot-Collisions/Solution.go +++ b/leetcode/2701-2800/2751.Robot-Collisions/Solution.go @@ -1,5 +1,73 @@ package Solution -func Solution(x bool) bool { - return x +import "sort" + +type tmp2751 struct { + i []int + p, h []int + d []byte +} + +func (t tmp2751) Len() int { + return len(t.p) +} + +func (t tmp2751) Swap(i, j int) { + t.p[i], t.p[j] = t.p[j], t.p[i] + t.h[i], t.h[j] = t.h[j], t.h[i] + t.d[i], t.d[j] = t.d[j], t.d[i] + t.i[i], t.i[j] = t.i[j], t.i[i] +} + +func (t tmp2751) Less(i, j int) bool { + return t.p[i] < t.p[j] +} + +func Solution(positions []int, healths []int, directions string) []int { + ans := make([]int, 0) + l := len(positions) + indies := make([]int, l) + for i := 0; i < l; i++ { + indies[i] = i + } + s := tmp2751{p: positions, h: healths, d: []byte(directions), i: indies} + sort.Sort(s) + + stack := make([]int, len(positions)) + stackIndex := -1 + for i := 0; i < l; i++ { + dir := s.d[i] + if dir == 'L' { + for stackIndex >= 0 && healths[stack[stackIndex]] < healths[i] { + healths[i]-- + stackIndex-- + } + + if stackIndex == -1 { + ans = append(ans, i) + continue + } + if healths[stack[stackIndex]] == healths[i] { + stackIndex-- + continue + } + + healths[stack[stackIndex]]-- + + continue + } + stackIndex++ + stack[stackIndex] = i + } + for i := 0; i <= stackIndex; i++ { + ans = append(ans, stack[i]) + } + sort.Slice(ans, func(i, j int) bool { + return indies[ans[i]] < indies[ans[j]] + }) + for i := 0; i < len(ans); i++ { + ans[i] = healths[ans[i]] + } + + return ans } diff --git a/leetcode/2701-2800/2751.Robot-Collisions/Solution_test.go b/leetcode/2701-2800/2751.Robot-Collisions/Solution_test.go index 14ff50eb4..6f3bd5d35 100755 --- a/leetcode/2701-2800/2751.Robot-Collisions/Solution_test.go +++ b/leetcode/2701-2800/2751.Robot-Collisions/Solution_test.go @@ -10,30 +10,31 @@ func TestSolution(t *testing.T) { // 测试用例 cases := []struct { name string - inputs bool - expect bool + p, h []int + d string + expect []int }{ - {"TestCase", true, true}, - {"TestCase", true, true}, - {"TestCase", false, false}, + {"TestCase1", []int{5, 4, 3, 2, 1}, []int{2, 17, 9, 15, 10}, "RRRRR", []int{2, 17, 9, 15, 10}}, + {"TestCase2", []int{3, 5, 2, 6}, []int{10, 10, 15, 12}, "RLRL", []int{14}}, + {"TestCase3", []int{1, 2, 5, 6}, []int{10, 10, 11, 11}, "RLRL", []int{}}, } // 开始测试 for i, c := range cases { t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { - got := Solution(c.inputs) + got := Solution(c.p, c.h, c.d) if !reflect.DeepEqual(got, c.expect) { - t.Fatalf("expected: %v, but got: %v, with inputs: %v", - c.expect, got, c.inputs) + t.Fatalf("expected: %v, but got: %v, with inputs: %v %v %v", + c.expect, got, c.p, c.h, c.d) } }) } } -// 压力测试 +// 压力测试 func BenchmarkSolution(b *testing.B) { } -// 使用案列 +// 使用案列 func ExampleSolution() { }