From 2802b2749046886feff0008df76091596f84297a Mon Sep 17 00:00:00 2001 From: yanglbme Date: Wed, 15 Nov 2023 10:54:23 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.2931 No.2931.Maximum Spending After Buying Items --- .../README.md | 109 +++++++++++++++++- .../README_EN.md | 109 +++++++++++++++++- .../Solution.cpp | 20 ++++ .../Solution.go | 24 ++++ .../Solution.java | 19 +++ .../Solution.py | 13 +++ .../Solution.ts | 18 +++ 7 files changed, 306 insertions(+), 6 deletions(-) create mode 100644 solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.cpp create mode 100644 solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.go create mode 100644 solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.java create mode 100644 solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.py create mode 100644 solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.ts diff --git a/solution/2900-2999/2931.Maximum Spending After Buying Items/README.md b/solution/2900-2999/2931.Maximum Spending After Buying Items/README.md index 9c521198423c2..7da39ea9f33c9 100644 --- a/solution/2900-2999/2931.Maximum Spending After Buying Items/README.md +++ b/solution/2900-2999/2931.Maximum Spending After Buying Items/README.md @@ -73,6 +73,14 @@ +**方法一:贪心 + 优先队列** + +根据题目描述,我们应该优先选择价值越小的物品,把价值越大的物品留到后面购买,这样才能使得总开销最大。因此,我们使用优先队列(小根堆)存储每个商店中还未购买的最小价值的物品。初始时,我们将每个商店中最右边的物品加入优先队列。 + +在每一天,我们从优先队列中取出价值最小的物品,将其加入答案,并将该物品所在商店中的上一个物品加入优先队列。我们重复上述操作,直到优先队列为空。 + +时间复杂度 $O(m \times n \times \log m)$,空间复杂度 $O(m)$。其中 $m$ 和 $n$ 分别是数组 $values$ 的行数和列数。 + ### **Python3** @@ -80,7 +88,19 @@ ```python - +class Solution: + def maxSpending(self, values: List[List[int]]) -> int: + n = len(values[0]) + pq = [(row[-1], i, n - 1) for i, row in enumerate(values)] + heapify(pq) + ans = d = 0 + while pq: + d += 1 + v, i, j = heappop(pq) + ans += v * d + if j: + heappush(pq, (values[i][j - 1], i, j - 1)) + return ans ``` ### **Java** @@ -88,19 +108,102 @@ ```java - +class Solution { + public long maxSpending(int[][] values) { + int m = values.length, n = values[0].length; + PriorityQueue pq = new PriorityQueue<>((a, b) -> a[0] - b[0]); + for (int i = 0; i < m; ++i) { + pq.offer(new int[] {values[i][n - 1], i, n - 1}); + } + long ans = 0; + for (int d = 1; !pq.isEmpty(); ++d) { + var p = pq.poll(); + int v = p[0], i = p[1], j = p[2]; + ans += (long) v * d; + if (j > 0) { + pq.offer(new int[] {values[i][j - 1], i, j - 1}); + } + } + return ans; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + long long maxSpending(vector>& values) { + priority_queue, vector>, greater>> pq; + int m = values.size(), n = values[0].size(); + for (int i = 0; i < m; ++i) { + pq.emplace(values[i][n - 1], i, n - 1); + } + long long ans = 0; + for (int d = 1; pq.size(); ++d) { + auto [v, i, j] = pq.top(); + pq.pop(); + ans += 1LL * v * d; + if (j) { + pq.emplace(values[i][j - 1], i, j - 1); + } + } + return ans; + } +}; ``` ### **Go** ```go +func maxSpending(values [][]int) (ans int64) { + pq := hp{} + n := len(values[0]) + for i, row := range values { + heap.Push(&pq, tuple{row[n-1], i, n - 1}) + } + for d := 1; len(pq) > 0; d++ { + p := heap.Pop(&pq).(tuple) + ans += int64(p.v * d) + if p.j > 0 { + heap.Push(&pq, tuple{values[p.i][p.j-1], p.i, p.j - 1}) + } + } + return +} + +type tuple struct{ v, i, j int } +type hp []tuple + +func (h hp) Len() int { return len(h) } +func (h hp) Less(i, j int) bool { return h[i].v < h[j].v } +func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] } +func (h *hp) Push(v any) { *h = append(*h, v.(tuple)) } +func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v } +``` +### **TypeScript** + +```ts +function maxSpending(values: number[][]): number { + const m = values.length; + const n = values[0].length; + const pq = new PriorityQueue({ compare: (a, b) => a[0] - b[0] }); + for (let i = 0; i < m; ++i) { + pq.enqueue([values[i][n - 1], i, n - 1]); + } + + let ans = 0; + for (let d = 1; !pq.isEmpty(); ++d) { + const [v, i, j] = pq.dequeue()!; + ans += v * d; + if (j > 0) { + pq.enqueue([values[i][j - 1], i, j - 1]); + } + } + return ans; +} ``` ### **...** diff --git a/solution/2900-2999/2931.Maximum Spending After Buying Items/README_EN.md b/solution/2900-2999/2931.Maximum Spending After Buying Items/README_EN.md index 089ec6ae163b3..a3993f6c852d6 100644 --- a/solution/2900-2999/2931.Maximum Spending After Buying Items/README_EN.md +++ b/solution/2900-2999/2931.Maximum Spending After Buying Items/README_EN.md @@ -67,30 +67,133 @@ It can be shown that 386 is the maximum amount of money that can be spent buying ## Solutions +**Solution 1: Greedy + Priority Queue** + +According to the problem description, we should prioritize purchasing items with smaller values and leave items with larger values to be purchased later in order to maximize the total cost. Therefore, we use a priority queue (min-heap) to store the smallest value item that has not been purchased in each store. Initially, we add the rightmost item in each store to the priority queue. + +Each day, we take out the item with the smallest value from the priority queue, add it to the answer, and add the previous item in the store where the item is located to the priority queue. We repeat the above operation until the priority queue is empty. + +The time complexity is $O(m \times n \times \log m)$, and the space complexity is $O(m)$. Here, $m$ and $n$ are the number of rows and columns of the array $values$, respectively. + ### **Python3** ```python - +class Solution: + def maxSpending(self, values: List[List[int]]) -> int: + n = len(values[0]) + pq = [(row[-1], i, n - 1) for i, row in enumerate(values)] + heapify(pq) + ans = d = 0 + while pq: + d += 1 + v, i, j = heappop(pq) + ans += v * d + if j: + heappush(pq, (values[i][j - 1], i, j - 1)) + return ans ``` ### **Java** ```java - +class Solution { + public long maxSpending(int[][] values) { + int m = values.length, n = values[0].length; + PriorityQueue pq = new PriorityQueue<>((a, b) -> a[0] - b[0]); + for (int i = 0; i < m; ++i) { + pq.offer(new int[] {values[i][n - 1], i, n - 1}); + } + long ans = 0; + for (int d = 1; !pq.isEmpty(); ++d) { + var p = pq.poll(); + int v = p[0], i = p[1], j = p[2]; + ans += (long) v * d; + if (j > 0) { + pq.offer(new int[] {values[i][j - 1], i, j - 1}); + } + } + return ans; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + long long maxSpending(vector>& values) { + priority_queue, vector>, greater>> pq; + int m = values.size(), n = values[0].size(); + for (int i = 0; i < m; ++i) { + pq.emplace(values[i][n - 1], i, n - 1); + } + long long ans = 0; + for (int d = 1; pq.size(); ++d) { + auto [v, i, j] = pq.top(); + pq.pop(); + ans += 1LL * v * d; + if (j) { + pq.emplace(values[i][j - 1], i, j - 1); + } + } + return ans; + } +}; ``` ### **Go** ```go +func maxSpending(values [][]int) (ans int64) { + pq := hp{} + n := len(values[0]) + for i, row := range values { + heap.Push(&pq, tuple{row[n-1], i, n - 1}) + } + for d := 1; len(pq) > 0; d++ { + p := heap.Pop(&pq).(tuple) + ans += int64(p.v * d) + if p.j > 0 { + heap.Push(&pq, tuple{values[p.i][p.j-1], p.i, p.j - 1}) + } + } + return +} + +type tuple struct{ v, i, j int } +type hp []tuple + +func (h hp) Len() int { return len(h) } +func (h hp) Less(i, j int) bool { return h[i].v < h[j].v } +func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] } +func (h *hp) Push(v any) { *h = append(*h, v.(tuple)) } +func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v } +``` +### **TypeScript** + +```ts +function maxSpending(values: number[][]): number { + const m = values.length; + const n = values[0].length; + const pq = new PriorityQueue({ compare: (a, b) => a[0] - b[0] }); + for (let i = 0; i < m; ++i) { + pq.enqueue([values[i][n - 1], i, n - 1]); + } + + let ans = 0; + for (let d = 1; !pq.isEmpty(); ++d) { + const [v, i, j] = pq.dequeue()!; + ans += v * d; + if (j > 0) { + pq.enqueue([values[i][j - 1], i, j - 1]); + } + } + return ans; +} ``` ### **...** diff --git a/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.cpp b/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.cpp new file mode 100644 index 0000000000000..5d0ebf9ede711 --- /dev/null +++ b/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.cpp @@ -0,0 +1,20 @@ +class Solution { +public: + long long maxSpending(vector>& values) { + priority_queue, vector>, greater>> pq; + int m = values.size(), n = values[0].size(); + for (int i = 0; i < m; ++i) { + pq.emplace(values[i][n - 1], i, n - 1); + } + long long ans = 0; + for (int d = 1; pq.size(); ++d) { + auto [v, i, j] = pq.top(); + pq.pop(); + ans += 1LL * v * d; + if (j) { + pq.emplace(values[i][j - 1], i, j - 1); + } + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.go b/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.go new file mode 100644 index 0000000000000..44fa6284522a1 --- /dev/null +++ b/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.go @@ -0,0 +1,24 @@ +func maxSpending(values [][]int) (ans int64) { + pq := hp{} + n := len(values[0]) + for i, row := range values { + heap.Push(&pq, tuple{row[n-1], i, n - 1}) + } + for d := 1; len(pq) > 0; d++ { + p := heap.Pop(&pq).(tuple) + ans += int64(p.v * d) + if p.j > 0 { + heap.Push(&pq, tuple{values[p.i][p.j-1], p.i, p.j - 1}) + } + } + return +} + +type tuple struct{ v, i, j int } +type hp []tuple + +func (h hp) Len() int { return len(h) } +func (h hp) Less(i, j int) bool { return h[i].v < h[j].v } +func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] } +func (h *hp) Push(v any) { *h = append(*h, v.(tuple)) } +func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v } \ No newline at end of file diff --git a/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.java b/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.java new file mode 100644 index 0000000000000..5c710193e01c3 --- /dev/null +++ b/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.java @@ -0,0 +1,19 @@ +class Solution { + public long maxSpending(int[][] values) { + int m = values.length, n = values[0].length; + PriorityQueue pq = new PriorityQueue<>((a, b) -> a[0] - b[0]); + for (int i = 0; i < m; ++i) { + pq.offer(new int[] {values[i][n - 1], i, n - 1}); + } + long ans = 0; + for (int d = 1; !pq.isEmpty(); ++d) { + var p = pq.poll(); + int v = p[0], i = p[1], j = p[2]; + ans += (long) v * d; + if (j > 0) { + pq.offer(new int[] {values[i][j - 1], i, j - 1}); + } + } + return ans; + } +} \ No newline at end of file diff --git a/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.py b/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.py new file mode 100644 index 0000000000000..58f3c569ef8c0 --- /dev/null +++ b/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.py @@ -0,0 +1,13 @@ +class Solution: + def maxSpending(self, values: List[List[int]]) -> int: + n = len(values[0]) + pq = [(row[-1], i, n - 1) for i, row in enumerate(values)] + heapify(pq) + ans = d = 0 + while pq: + d += 1 + v, i, j = heappop(pq) + ans += v * d + if j: + heappush(pq, (values[i][j - 1], i, j - 1)) + return ans diff --git a/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.ts b/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.ts new file mode 100644 index 0000000000000..dcba766ad2dcb --- /dev/null +++ b/solution/2900-2999/2931.Maximum Spending After Buying Items/Solution.ts @@ -0,0 +1,18 @@ +function maxSpending(values: number[][]): number { + const m = values.length; + const n = values[0].length; + const pq = new PriorityQueue({ compare: (a, b) => a[0] - b[0] }); + for (let i = 0; i < m; ++i) { + pq.enqueue([values[i][n - 1], i, n - 1]); + } + + let ans = 0; + for (let d = 1; !pq.isEmpty(); ++d) { + const [v, i, j] = pq.dequeue()!; + ans += v * d; + if (j > 0) { + pq.enqueue([values[i][j - 1], i, j - 1]); + } + } + return ans; +}