diff --git "a/lcof/\351\235\242\350\257\225\351\242\23046. \346\212\212\346\225\260\345\255\227\347\277\273\350\257\221\346\210\220\345\255\227\347\254\246\344\270\262/README.md" "b/lcof/\351\235\242\350\257\225\351\242\23046. \346\212\212\346\225\260\345\255\227\347\277\273\350\257\221\346\210\220\345\255\227\347\254\246\344\270\262/README.md" index 98773024f9f8a..f0442ed4c037a 100644 --- "a/lcof/\351\235\242\350\257\225\351\242\23046. \346\212\212\346\225\260\345\255\227\347\277\273\350\257\221\346\210\220\345\255\227\347\254\246\344\270\262/README.md" +++ "b/lcof/\351\235\242\350\257\225\351\242\23046. \346\212\212\346\225\260\345\255\227\347\277\273\350\257\221\346\210\220\345\255\227\347\254\246\344\270\262/README.md" @@ -40,12 +40,12 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9 我们先将数字 `num` 转为字符串 $s$,字符串 $s$ 的长度记为 $n$。 -然后我们设计一个函数 $dfs(i)$,表示从第 $i$ 个数字开始的不同翻译的数目。那么答案就是 $dfs(0)$。 +然后我们设计一个函数 $dfs(i)$,表示从索引为 $i$ 的数字开始的不同翻译的数目。那么答案就是 $dfs(0)$。 函数 $dfs(i)$ 的计算如下: -- 如果 $i \ge n - 1$,说明已经翻译到最后一个数字,只有一种翻译方法,返回 $1$; -- 否则,我们可以选择翻译第 $i$ 个数字,此时翻译方法数目为 $dfs(i + 1)$;如果第 $i$ 个数字和第 $i + 1$ 个数字可以组成一个有效的字符(即 $s[i] == 1$ 或者 $s[i] == 2$ 且 $s[i + 1] \lt 6$),那么我们还可以选择翻译第 $i$ 和第 $i + 1$ 个数字,此时翻译方法数目为 $dfs(i + 2)$。因此 $dfs(i) = dfs(i+1) + dfs(i+2)$。 +- 如果 $i \ge n - 1$,说明已经翻译到最后一个数字或者越过最后一个字符,均只有一种翻译方法,返回 $1$; +- 否则,我们可以选择翻译索引为 $i$ 的数字,此时翻译方法数目为 $dfs(i + 1)$;如果索引为 $i$ 的数字和索引为 $i + 1$ 的数字可以组成一个有效的字符(即 $s[i] == 1$ 或者 $s[i] == 2$ 且 $s[i + 1] \lt 6$),那么我们还可以选择翻译索引为 $i$ 和索引为 $i + 1$ 的数字,此时翻译方法数目为 $dfs(i + 2)$。因此 $dfs(i) = dfs(i+1) + dfs(i+2)$。 过程中我们可以使用记忆化搜索,将已经计算过的 $dfs(i)$ 的值存储起来,避免重复计算。 diff --git a/solution/0300-0399/0370.Range Addition/README.md b/solution/0300-0399/0370.Range Addition/README.md index 107a47d8f9599..20ddbdccebd7e 100644 --- a/solution/0300-0399/0370.Range Addition/README.md +++ b/solution/0300-0399/0370.Range Addition/README.md @@ -101,12 +101,16 @@ class Solution { public: vector getModifiedArray(int length, vector>& updates) { vector d(length); - for (auto& e : updates) { + for (const auto& e : updates) { int l = e[0], r = e[1], c = e[2]; d[l] += c; - if (r + 1 < length) d[r + 1] -= c; + if (r + 1 < length) { + d[r + 1] -= c; + } + } + for (int i = 1; i < length; ++i) { + d[i] += d[i - 1]; } - for (int i = 1; i < length; ++i) d[i] += d[i - 1]; return d; } }; @@ -131,6 +135,24 @@ func getModifiedArray(length int, updates [][]int) []int { } ``` +#### TypeScript + +```ts +function getModifiedArray(length: number, updates: number[][]): number[] { + const d: number[] = Array(length).fill(0); + for (const [l, r, c] of updates) { + d[l] += c; + if (r + 1 < length) { + d[r + 1] -= c; + } + } + for (let i = 1; i < length; ++i) { + d[i] += d[i - 1]; + } + return d; +} +``` + #### JavaScript ```js @@ -140,7 +162,7 @@ func getModifiedArray(length int, updates [][]int) []int { * @return {number[]} */ var getModifiedArray = function (length, updates) { - const d = new Array(length).fill(0); + const d = Array(length).fill(0); for (const [l, r, c] of updates) { d[l] += c; if (r + 1 < length) { @@ -177,82 +199,74 @@ var getModifiedArray = function (length, updates) { ```python class BinaryIndexedTree: - def __init__(self, n): + __slots__ = "n", "c" + + def __init__(self, n: int): self.n = n self.c = [0] * (n + 1) - @staticmethod - def lowbit(x): - return x & -x - - def update(self, x, delta): + def update(self, x: int, delta: int) -> None: while x <= self.n: self.c[x] += delta - x += BinaryIndexedTree.lowbit(x) + x += x & -x - def query(self, x): + def query(self, x: int) -> int: s = 0 while x: s += self.c[x] - x -= BinaryIndexedTree.lowbit(x) + x -= x & -x return s class Solution: def getModifiedArray(self, length: int, updates: List[List[int]]) -> List[int]: tree = BinaryIndexedTree(length) - for start, end, inc in updates: - tree.update(start + 1, inc) - tree.update(end + 2, -inc) + for l, r, c in updates: + tree.update(l + 1, c) + tree.update(r + 2, -c) return [tree.query(i + 1) for i in range(length)] ``` #### Java ```java -class Solution { - public int[] getModifiedArray(int length, int[][] updates) { - BinaryIndexedTree tree = new BinaryIndexedTree(length); - for (int[] e : updates) { - int start = e[0], end = e[1], inc = e[2]; - tree.update(start + 1, inc); - tree.update(end + 2, -inc); - } - int[] ans = new int[length]; - for (int i = 0; i < length; ++i) { - ans[i] = tree.query(i + 1); - } - return ans; - } -} - class BinaryIndexedTree { private int n; private int[] c; public BinaryIndexedTree(int n) { this.n = n; - c = new int[n + 1]; + this.c = new int[n + 1]; } public void update(int x, int delta) { - while (x <= n) { + for (; x <= n; x += x & -x) { c[x] += delta; - x += lowbit(x); } } public int query(int x) { int s = 0; - while (x > 0) { + for (; x > 0; x -= x & -x) { s += c[x]; - x -= lowbit(x); } return s; } +} - public static int lowbit(int x) { - return x & -x; +class Solution { + public int[] getModifiedArray(int length, int[][] updates) { + var tree = new BinaryIndexedTree(length); + for (var e : updates) { + int l = e[0], r = e[1], c = e[2]; + tree.update(l + 1, c); + tree.update(r + 2, -c); + } + int[] ans = new int[length]; + for (int i = 0; i < length; ++i) { + ans[i] = tree.query(i + 1); + } + return ans; } } ``` @@ -261,46 +275,43 @@ class BinaryIndexedTree { ```cpp class BinaryIndexedTree { -public: +private: int n; vector c; - BinaryIndexedTree(int _n) - : n(_n) - , c(_n + 1) {} +public: + BinaryIndexedTree(int n) + : n(n) + , c(n + 1) {} void update(int x, int delta) { - while (x <= n) { + for (; x <= n; x += x & -x) { c[x] += delta; - x += lowbit(x); } } int query(int x) { int s = 0; - while (x > 0) { + for (; x > 0; x -= x & -x) { s += c[x]; - x -= lowbit(x); } return s; } - - int lowbit(int x) { - return x & -x; - } }; class Solution { public: vector getModifiedArray(int length, vector>& updates) { BinaryIndexedTree* tree = new BinaryIndexedTree(length); - for (auto& e : updates) { - int start = e[0], end = e[1], inc = e[2]; - tree->update(start + 1, inc); - tree->update(end + 2, -inc); + for (const auto& e : updates) { + int l = e[0], r = e[1], c = e[2]; + tree->update(l + 1, c); + tree->update(r + 2, -c); } vector ans; - for (int i = 0; i < length; ++i) ans.push_back(tree->query(i + 1)); + for (int i = 0; i < length; ++i) { + ans.push_back(tree->query(i + 1)); + } return ans; } }; @@ -314,46 +325,116 @@ type BinaryIndexedTree struct { c []int } -func newBinaryIndexedTree(n int) *BinaryIndexedTree { - c := make([]int, n+1) - return &BinaryIndexedTree{n, c} +func NewBinaryIndexedTree(n int) *BinaryIndexedTree { + return &BinaryIndexedTree{n: n, c: make([]int, n+1)} } -func (this *BinaryIndexedTree) lowbit(x int) int { - return x & -x -} - -func (this *BinaryIndexedTree) update(x, delta int) { - for x <= this.n { - this.c[x] += delta - x += this.lowbit(x) +func (bit *BinaryIndexedTree) update(x, delta int) { + for ; x <= bit.n; x += x & -x { + bit.c[x] += delta } } -func (this *BinaryIndexedTree) query(x int) int { +func (bit *BinaryIndexedTree) query(x int) int { s := 0 - for x > 0 { - s += this.c[x] - x -= this.lowbit(x) + for ; x > 0; x -= x & -x { + s += bit.c[x] } return s } -func getModifiedArray(length int, updates [][]int) []int { - tree := newBinaryIndexedTree(length) +func getModifiedArray(length int, updates [][]int) (ans []int) { + bit := NewBinaryIndexedTree(length) for _, e := range updates { - start, end, inc := e[0], e[1], e[2] - tree.update(start+1, inc) - tree.update(end+2, -inc) + l, r, c := e[0], e[1], e[2] + bit.update(l+1, c) + bit.update(r+2, -c) } - ans := make([]int, length) - for i := range ans { - ans[i] = tree.query(i + 1) + for i := 1; i <= length; i++ { + ans = append(ans, bit.query(i)) } - return ans + return } ``` +#### TypeScript + +```ts +class BinaryIndexedTree { + private n: number; + private c: number[]; + + constructor(n: number) { + this.n = n; + this.c = Array(n + 1).fill(0); + } + + update(x: number, delta: number): void { + for (; x <= this.n; x += x & -x) { + this.c[x] += delta; + } + } + + query(x: number): number { + let s = 0; + for (; x > 0; x -= x & -x) { + s += this.c[x]; + } + return s; + } +} + +function getModifiedArray(length: number, updates: number[][]): number[] { + const bit = new BinaryIndexedTree(length); + for (const [l, r, c] of updates) { + bit.update(l + 1, c); + bit.update(r + 2, -c); + } + return Array.from({ length }, (_, i) => bit.query(i + 1)); +} +``` + +#### JavaScript + +```js +/** + * @param {number} length + * @param {number[][]} updates + * @return {number[]} + */ +var getModifiedArray = function (length, updates) { + class BinaryIndexedTree { + constructor(n) { + this.n = n; + this.c = Array(n + 1).fill(0); + } + + update(x, delta) { + while (x <= this.n) { + this.c[x] += delta; + x += x & -x; + } + } + + query(x) { + let s = 0; + while (x > 0) { + s += this.c[x]; + x -= x & -x; + } + return s; + } + } + + const bit = new BinaryIndexedTree(length); + for (const [l, r, c] of updates) { + bit.update(l + 1, c); + bit.update(r + 2, -c); + } + return Array.from({ length }, (_, i) => bit.query(i + 1)); +}; +``` + diff --git a/solution/0300-0399/0370.Range Addition/README_EN.md b/solution/0300-0399/0370.Range Addition/README_EN.md index 2c25b07ab487c..191ad3559961e 100644 --- a/solution/0300-0399/0370.Range Addition/README_EN.md +++ b/solution/0300-0399/0370.Range Addition/README_EN.md @@ -54,7 +54,13 @@ tags: -### Solution 1 +### Solution 1: Difference Array + +This is a template problem for difference arrays. + +We define $d$ as the difference array. To add $c$ to each number in the interval $[l,..r]$, we set $d[l] += c$ and $d[r+1] -= c$. Finally, we compute the prefix sum of the difference array to obtain the original array. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. @@ -99,12 +105,16 @@ class Solution { public: vector getModifiedArray(int length, vector>& updates) { vector d(length); - for (auto& e : updates) { + for (const auto& e : updates) { int l = e[0], r = e[1], c = e[2]; d[l] += c; - if (r + 1 < length) d[r + 1] -= c; + if (r + 1 < length) { + d[r + 1] -= c; + } + } + for (int i = 1; i < length; ++i) { + d[i] += d[i - 1]; } - for (int i = 1; i < length; ++i) d[i] += d[i - 1]; return d; } }; @@ -129,6 +139,24 @@ func getModifiedArray(length int, updates [][]int) []int { } ``` +#### TypeScript + +```ts +function getModifiedArray(length: number, updates: number[][]): number[] { + const d: number[] = Array(length).fill(0); + for (const [l, r, c] of updates) { + d[l] += c; + if (r + 1 < length) { + d[r + 1] -= c; + } + } + for (let i = 1; i < length; ++i) { + d[i] += d[i - 1]; + } + return d; +} +``` + #### JavaScript ```js @@ -138,7 +166,7 @@ func getModifiedArray(length int, updates [][]int) []int { * @return {number[]} */ var getModifiedArray = function (length, updates) { - const d = new Array(length).fill(0); + const d = Array(length).fill(0); for (const [l, r, c] of updates) { d[l] += c; if (r + 1 < length) { @@ -158,7 +186,16 @@ var getModifiedArray = function (length, updates) { -### Solution 2 +### Solution 2: Binary Indexed Tree + Difference Array + +The time complexity is $O(n \times \log n)$. + +A Binary Indexed Tree (BIT), also known as a Fenwick Tree, can efficiently perform the following two operations: + +1. **Point Update** `update(x, delta)`: Add a value $delta$ to the number at position $x$ in the sequence. +2. **Prefix Sum Query** `query(x)`: Query the sum of the interval $[1, ... , x]$ in the sequence, i.e., the prefix sum up to position $x$. + +The time complexity for both operations is $O(\log n)$. @@ -166,82 +203,76 @@ var getModifiedArray = function (length, updates) { ```python class BinaryIndexedTree: - def __init__(self, n): + __slots__ = "n", "c" + + def __init__(self, n: int): self.n = n self.c = [0] * (n + 1) - @staticmethod - def lowbit(x): - return x & -x - - def update(self, x, delta): + def update(self, x: int, delta: int) -> None: while x <= self.n: self.c[x] += delta - x += BinaryIndexedTree.lowbit(x) + x += x & -x - def query(self, x): + def query(self, x: int) -> int: s = 0 while x: s += self.c[x] - x -= BinaryIndexedTree.lowbit(x) + x -= x & -x return s class Solution: def getModifiedArray(self, length: int, updates: List[List[int]]) -> List[int]: tree = BinaryIndexedTree(length) - for start, end, inc in updates: - tree.update(start + 1, inc) - tree.update(end + 2, -inc) + for l, r, c in updates: + tree.update(l + 1, c) + tree.update(r + 2, -c) return [tree.query(i + 1) for i in range(length)] ``` +l + #### Java ```java -class Solution { - public int[] getModifiedArray(int length, int[][] updates) { - BinaryIndexedTree tree = new BinaryIndexedTree(length); - for (int[] e : updates) { - int start = e[0], end = e[1], inc = e[2]; - tree.update(start + 1, inc); - tree.update(end + 2, -inc); - } - int[] ans = new int[length]; - for (int i = 0; i < length; ++i) { - ans[i] = tree.query(i + 1); - } - return ans; - } -} - class BinaryIndexedTree { private int n; private int[] c; public BinaryIndexedTree(int n) { this.n = n; - c = new int[n + 1]; + this.c = new int[n + 1]; } public void update(int x, int delta) { - while (x <= n) { + for (; x <= n; x += x & -x) { c[x] += delta; - x += lowbit(x); } } public int query(int x) { int s = 0; - while (x > 0) { + for (; x > 0; x -= x & -x) { s += c[x]; - x -= lowbit(x); } return s; } +} - public static int lowbit(int x) { - return x & -x; +class Solution { + public int[] getModifiedArray(int length, int[][] updates) { + var tree = new BinaryIndexedTree(length); + for (var e : updates) { + int l = e[0], r = e[1], c = e[2]; + tree.update(l + 1, c); + tree.update(r + 2, -c); + } + int[] ans = new int[length]; + for (int i = 0; i < length; ++i) { + ans[i] = tree.query(i + 1); + } + return ans; } } ``` @@ -250,46 +281,43 @@ class BinaryIndexedTree { ```cpp class BinaryIndexedTree { -public: +private: int n; vector c; - BinaryIndexedTree(int _n) - : n(_n) - , c(_n + 1) {} +public: + BinaryIndexedTree(int n) + : n(n) + , c(n + 1) {} void update(int x, int delta) { - while (x <= n) { + for (; x <= n; x += x & -x) { c[x] += delta; - x += lowbit(x); } } int query(int x) { int s = 0; - while (x > 0) { + for (; x > 0; x -= x & -x) { s += c[x]; - x -= lowbit(x); } return s; } - - int lowbit(int x) { - return x & -x; - } }; class Solution { public: vector getModifiedArray(int length, vector>& updates) { BinaryIndexedTree* tree = new BinaryIndexedTree(length); - for (auto& e : updates) { - int start = e[0], end = e[1], inc = e[2]; - tree->update(start + 1, inc); - tree->update(end + 2, -inc); + for (const auto& e : updates) { + int l = e[0], r = e[1], c = e[2]; + tree->update(l + 1, c); + tree->update(r + 2, -c); } vector ans; - for (int i = 0; i < length; ++i) ans.push_back(tree->query(i + 1)); + for (int i = 0; i < length; ++i) { + ans.push_back(tree->query(i + 1)); + } return ans; } }; @@ -303,46 +331,116 @@ type BinaryIndexedTree struct { c []int } -func newBinaryIndexedTree(n int) *BinaryIndexedTree { - c := make([]int, n+1) - return &BinaryIndexedTree{n, c} +func NewBinaryIndexedTree(n int) *BinaryIndexedTree { + return &BinaryIndexedTree{n: n, c: make([]int, n+1)} } -func (this *BinaryIndexedTree) lowbit(x int) int { - return x & -x -} - -func (this *BinaryIndexedTree) update(x, delta int) { - for x <= this.n { - this.c[x] += delta - x += this.lowbit(x) +func (bit *BinaryIndexedTree) update(x, delta int) { + for ; x <= bit.n; x += x & -x { + bit.c[x] += delta } } -func (this *BinaryIndexedTree) query(x int) int { +func (bit *BinaryIndexedTree) query(x int) int { s := 0 - for x > 0 { - s += this.c[x] - x -= this.lowbit(x) + for ; x > 0; x -= x & -x { + s += bit.c[x] } return s } -func getModifiedArray(length int, updates [][]int) []int { - tree := newBinaryIndexedTree(length) +func getModifiedArray(length int, updates [][]int) (ans []int) { + bit := NewBinaryIndexedTree(length) for _, e := range updates { - start, end, inc := e[0], e[1], e[2] - tree.update(start+1, inc) - tree.update(end+2, -inc) + l, r, c := e[0], e[1], e[2] + bit.update(l+1, c) + bit.update(r+2, -c) } - ans := make([]int, length) - for i := range ans { - ans[i] = tree.query(i + 1) + for i := 1; i <= length; i++ { + ans = append(ans, bit.query(i)) } - return ans + return } ``` +#### TypeScript + +```ts +class BinaryIndexedTree { + private n: number; + private c: number[]; + + constructor(n: number) { + this.n = n; + this.c = Array(n + 1).fill(0); + } + + update(x: number, delta: number): void { + for (; x <= this.n; x += x & -x) { + this.c[x] += delta; + } + } + + query(x: number): number { + let s = 0; + for (; x > 0; x -= x & -x) { + s += this.c[x]; + } + return s; + } +} + +function getModifiedArray(length: number, updates: number[][]): number[] { + const bit = new BinaryIndexedTree(length); + for (const [l, r, c] of updates) { + bit.update(l + 1, c); + bit.update(r + 2, -c); + } + return Array.from({ length }, (_, i) => bit.query(i + 1)); +} +``` + +#### JavaScript + +```js +/** + * @param {number} length + * @param {number[][]} updates + * @return {number[]} + */ +var getModifiedArray = function (length, updates) { + class BinaryIndexedTree { + constructor(n) { + this.n = n; + this.c = Array(n + 1).fill(0); + } + + update(x, delta) { + while (x <= this.n) { + this.c[x] += delta; + x += x & -x; + } + } + + query(x) { + let s = 0; + while (x > 0) { + s += this.c[x]; + x -= x & -x; + } + return s; + } + } + + const bit = new BinaryIndexedTree(length); + for (const [l, r, c] of updates) { + bit.update(l + 1, c); + bit.update(r + 2, -c); + } + return Array.from({ length }, (_, i) => bit.query(i + 1)); +}; +``` + diff --git a/solution/0300-0399/0370.Range Addition/Solution.cpp b/solution/0300-0399/0370.Range Addition/Solution.cpp index 15784241b62ee..3da2a9f884ca8 100644 --- a/solution/0300-0399/0370.Range Addition/Solution.cpp +++ b/solution/0300-0399/0370.Range Addition/Solution.cpp @@ -2,12 +2,16 @@ class Solution { public: vector getModifiedArray(int length, vector>& updates) { vector d(length); - for (auto& e : updates) { + for (const auto& e : updates) { int l = e[0], r = e[1], c = e[2]; d[l] += c; - if (r + 1 < length) d[r + 1] -= c; + if (r + 1 < length) { + d[r + 1] -= c; + } + } + for (int i = 1; i < length; ++i) { + d[i] += d[i - 1]; } - for (int i = 1; i < length; ++i) d[i] += d[i - 1]; return d; } -}; \ No newline at end of file +}; diff --git a/solution/0300-0399/0370.Range Addition/Solution.js b/solution/0300-0399/0370.Range Addition/Solution.js index 0be14fd405507..3eaff3488c50a 100644 --- a/solution/0300-0399/0370.Range Addition/Solution.js +++ b/solution/0300-0399/0370.Range Addition/Solution.js @@ -4,7 +4,7 @@ * @return {number[]} */ var getModifiedArray = function (length, updates) { - const d = new Array(length).fill(0); + const d = Array(length).fill(0); for (const [l, r, c] of updates) { d[l] += c; if (r + 1 < length) { diff --git a/solution/0300-0399/0370.Range Addition/Solution.ts b/solution/0300-0399/0370.Range Addition/Solution.ts new file mode 100644 index 0000000000000..9d5e778e7884c --- /dev/null +++ b/solution/0300-0399/0370.Range Addition/Solution.ts @@ -0,0 +1,13 @@ +function getModifiedArray(length: number, updates: number[][]): number[] { + const d: number[] = Array(length).fill(0); + for (const [l, r, c] of updates) { + d[l] += c; + if (r + 1 < length) { + d[r + 1] -= c; + } + } + for (let i = 1; i < length; ++i) { + d[i] += d[i - 1]; + } + return d; +} diff --git a/solution/0300-0399/0370.Range Addition/Solution2.cpp b/solution/0300-0399/0370.Range Addition/Solution2.cpp index 4e661b4191c48..9aa0c6fc41542 100644 --- a/solution/0300-0399/0370.Range Addition/Solution2.cpp +++ b/solution/0300-0399/0370.Range Addition/Solution2.cpp @@ -1,44 +1,41 @@ class BinaryIndexedTree { -public: +private: int n; vector c; - BinaryIndexedTree(int _n) - : n(_n) - , c(_n + 1) {} +public: + BinaryIndexedTree(int n) + : n(n) + , c(n + 1) {} void update(int x, int delta) { - while (x <= n) { + for (; x <= n; x += x & -x) { c[x] += delta; - x += lowbit(x); } } int query(int x) { int s = 0; - while (x > 0) { + for (; x > 0; x -= x & -x) { s += c[x]; - x -= lowbit(x); } return s; } - - int lowbit(int x) { - return x & -x; - } }; class Solution { public: vector getModifiedArray(int length, vector>& updates) { BinaryIndexedTree* tree = new BinaryIndexedTree(length); - for (auto& e : updates) { - int start = e[0], end = e[1], inc = e[2]; - tree->update(start + 1, inc); - tree->update(end + 2, -inc); + for (const auto& e : updates) { + int l = e[0], r = e[1], c = e[2]; + tree->update(l + 1, c); + tree->update(r + 2, -c); } vector ans; - for (int i = 0; i < length; ++i) ans.push_back(tree->query(i + 1)); + for (int i = 0; i < length; ++i) { + ans.push_back(tree->query(i + 1)); + } return ans; } -}; \ No newline at end of file +}; diff --git a/solution/0300-0399/0370.Range Addition/Solution2.go b/solution/0300-0399/0370.Range Addition/Solution2.go index d5b3877030f7c..c53a1226550c6 100644 --- a/solution/0300-0399/0370.Range Addition/Solution2.go +++ b/solution/0300-0399/0370.Range Addition/Solution2.go @@ -3,41 +3,33 @@ type BinaryIndexedTree struct { c []int } -func newBinaryIndexedTree(n int) *BinaryIndexedTree { - c := make([]int, n+1) - return &BinaryIndexedTree{n, c} +func NewBinaryIndexedTree(n int) *BinaryIndexedTree { + return &BinaryIndexedTree{n: n, c: make([]int, n+1)} } -func (this *BinaryIndexedTree) lowbit(x int) int { - return x & -x -} - -func (this *BinaryIndexedTree) update(x, delta int) { - for x <= this.n { - this.c[x] += delta - x += this.lowbit(x) +func (bit *BinaryIndexedTree) update(x, delta int) { + for ; x <= bit.n; x += x & -x { + bit.c[x] += delta } } -func (this *BinaryIndexedTree) query(x int) int { +func (bit *BinaryIndexedTree) query(x int) int { s := 0 - for x > 0 { - s += this.c[x] - x -= this.lowbit(x) + for ; x > 0; x -= x & -x { + s += bit.c[x] } return s } -func getModifiedArray(length int, updates [][]int) []int { - tree := newBinaryIndexedTree(length) +func getModifiedArray(length int, updates [][]int) (ans []int) { + bit := NewBinaryIndexedTree(length) for _, e := range updates { - start, end, inc := e[0], e[1], e[2] - tree.update(start+1, inc) - tree.update(end+2, -inc) + l, r, c := e[0], e[1], e[2] + bit.update(l+1, c) + bit.update(r+2, -c) } - ans := make([]int, length) - for i := range ans { - ans[i] = tree.query(i + 1) + for i := 1; i <= length; i++ { + ans = append(ans, bit.query(i)) } - return ans -} \ No newline at end of file + return +} diff --git a/solution/0300-0399/0370.Range Addition/Solution2.java b/solution/0300-0399/0370.Range Addition/Solution2.java index a7c3194be1fca..567586dfb4fc0 100644 --- a/solution/0300-0399/0370.Range Addition/Solution2.java +++ b/solution/0300-0399/0370.Range Addition/Solution2.java @@ -1,45 +1,39 @@ -class Solution { - public int[] getModifiedArray(int length, int[][] updates) { - BinaryIndexedTree tree = new BinaryIndexedTree(length); - for (int[] e : updates) { - int start = e[0], end = e[1], inc = e[2]; - tree.update(start + 1, inc); - tree.update(end + 2, -inc); - } - int[] ans = new int[length]; - for (int i = 0; i < length; ++i) { - ans[i] = tree.query(i + 1); - } - return ans; - } -} - class BinaryIndexedTree { private int n; private int[] c; public BinaryIndexedTree(int n) { this.n = n; - c = new int[n + 1]; + this.c = new int[n + 1]; } public void update(int x, int delta) { - while (x <= n) { + for (; x <= n; x += x & -x) { c[x] += delta; - x += lowbit(x); } } public int query(int x) { int s = 0; - while (x > 0) { + for (; x > 0; x -= x & -x) { s += c[x]; - x -= lowbit(x); } return s; } +} - public static int lowbit(int x) { - return x & -x; +class Solution { + public int[] getModifiedArray(int length, int[][] updates) { + var tree = new BinaryIndexedTree(length); + for (var e : updates) { + int l = e[0], r = e[1], c = e[2]; + tree.update(l + 1, c); + tree.update(r + 2, -c); + } + int[] ans = new int[length]; + for (int i = 0; i < length; ++i) { + ans[i] = tree.query(i + 1); + } + return ans; } -} \ No newline at end of file +} diff --git a/solution/0300-0399/0370.Range Addition/Solution2.js b/solution/0300-0399/0370.Range Addition/Solution2.js new file mode 100644 index 0000000000000..17317452a1d12 --- /dev/null +++ b/solution/0300-0399/0370.Range Addition/Solution2.js @@ -0,0 +1,36 @@ +/** + * @param {number} length + * @param {number[][]} updates + * @return {number[]} + */ +var getModifiedArray = function (length, updates) { + class BinaryIndexedTree { + constructor(n) { + this.n = n; + this.c = Array(n + 1).fill(0); + } + + update(x, delta) { + while (x <= this.n) { + this.c[x] += delta; + x += x & -x; + } + } + + query(x) { + let s = 0; + while (x > 0) { + s += this.c[x]; + x -= x & -x; + } + return s; + } + } + + const bit = new BinaryIndexedTree(length); + for (const [l, r, c] of updates) { + bit.update(l + 1, c); + bit.update(r + 2, -c); + } + return Array.from({ length }, (_, i) => bit.query(i + 1)); +}; diff --git a/solution/0300-0399/0370.Range Addition/Solution2.py b/solution/0300-0399/0370.Range Addition/Solution2.py index ffdd09fd6c50f..2657081c764d2 100644 --- a/solution/0300-0399/0370.Range Addition/Solution2.py +++ b/solution/0300-0399/0370.Range Addition/Solution2.py @@ -1,29 +1,27 @@ class BinaryIndexedTree: - def __init__(self, n): + __slots__ = "n", "c" + + def __init__(self, n: int): self.n = n self.c = [0] * (n + 1) - @staticmethod - def lowbit(x): - return x & -x - - def update(self, x, delta): + def update(self, x: int, delta: int) -> None: while x <= self.n: self.c[x] += delta - x += BinaryIndexedTree.lowbit(x) + x += x & -x - def query(self, x): + def query(self, x: int) -> int: s = 0 while x: s += self.c[x] - x -= BinaryIndexedTree.lowbit(x) + x -= x & -x return s class Solution: def getModifiedArray(self, length: int, updates: List[List[int]]) -> List[int]: tree = BinaryIndexedTree(length) - for start, end, inc in updates: - tree.update(start + 1, inc) - tree.update(end + 2, -inc) + for l, r, c in updates: + tree.update(l + 1, c) + tree.update(r + 2, -c) return [tree.query(i + 1) for i in range(length)] diff --git a/solution/0300-0399/0370.Range Addition/Solution2.ts b/solution/0300-0399/0370.Range Addition/Solution2.ts new file mode 100644 index 0000000000000..590691a46a0d9 --- /dev/null +++ b/solution/0300-0399/0370.Range Addition/Solution2.ts @@ -0,0 +1,32 @@ +class BinaryIndexedTree { + private n: number; + private c: number[]; + + constructor(n: number) { + this.n = n; + this.c = Array(n + 1).fill(0); + } + + update(x: number, delta: number): void { + for (; x <= this.n; x += x & -x) { + this.c[x] += delta; + } + } + + query(x: number): number { + let s = 0; + for (; x > 0; x -= x & -x) { + s += this.c[x]; + } + return s; + } +} + +function getModifiedArray(length: number, updates: number[][]): number[] { + const bit = new BinaryIndexedTree(length); + for (const [l, r, c] of updates) { + bit.update(l + 1, c); + bit.update(r + 2, -c); + } + return Array.from({ length }, (_, i) => bit.query(i + 1)); +} diff --git a/solution/0400-0499/0496.Next Greater Element I/README.md b/solution/0400-0499/0496.Next Greater Element I/README.md index 88ce5651baae0..d321f2b53c511 100644 --- a/solution/0400-0499/0496.Next Greater Element I/README.md +++ b/solution/0400-0499/0496.Next Greater Element I/README.md @@ -72,19 +72,13 @@ tags: ### 方法一:单调栈 -单调栈常见模型:找出每个数左/右边**离它最近的**且**比它大/小的数**。模板: +我们可以从右往左遍历数组 $\textit{nums2}$,维护一个从栈顶到栈底单调递增的栈 $\textit{stk}$,并且用哈希表 $\textit{d}$ 记录每个元素的下一个更大元素。 -```python -stk = [] -for i in range(n): - while stk and check(stk[-1], i): - stk.pop() - stk.append(i) -``` +遍历到元素 $x$ 时,如果栈不为空且栈顶元素小于 $x$,我们就不断弹出栈顶元素,直到栈为空或者栈顶元素大于等于 $x$。此时,如果栈不为空,栈顶元素就是 $x$ 的下一个更大元素,否则 $x$ 没有下一个更大元素。 -对于本题,先对将 `nums2` 中的每一个元素,求出其下一个更大的元素。随后对于将这些答案放入哈希表 $m$ 中,再遍历数组 `nums1`,并直接找出答案。对于 `nums2`,可以使用单调栈来解决这个问题。 +最后我们遍历数组 $\textit{nums1}$,根据哈希表 $\textit{d}$ 得到答案。 -时间复杂度 $O(M+N)$,其中 $M$ 和 $N$ 分别为数组 `nums1` 和 `nums2` 的长度。 +时间复杂度 $O(m + n)$,空间复杂度 $O(n)$。其中 $m$ 和 $n$ 分别为数组 $\textit{nums1}$ 和 $\textit{nums2}$ 的长度。 @@ -93,13 +87,15 @@ for i in range(n): ```python class Solution: def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: - m = {} stk = [] - for v in nums2: - while stk and stk[-1] < v: - m[stk.pop()] = v - stk.append(v) - return [m.get(v, -1) for v in nums1] + d = {} + for x in nums2[::-1]: + while stk and stk[-1] < x: + stk.pop() + if stk: + d[x] = stk[-1] + stk.append(x) + return [d.get(x, -1) for x in nums1] ``` #### Java @@ -108,17 +104,21 @@ class Solution: class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { Deque stk = new ArrayDeque<>(); - Map m = new HashMap<>(); - for (int v : nums2) { - while (!stk.isEmpty() && stk.peek() < v) { - m.put(stk.pop(), v); + int m = nums1.length, n = nums2.length; + Map d = new HashMap(n); + for (int i = n - 1; i >= 0; --i) { + int x = nums2[i]; + while (!stk.isEmpty() && stk.peek() < x) { + stk.pop(); + } + if (!stk.isEmpty()) { + d.put(x, stk.peek()); } - stk.push(v); + stk.push(x); } - int n = nums1.length; - int[] ans = new int[n]; - for (int i = 0; i < n; ++i) { - ans[i] = m.getOrDefault(nums1[i], -1); + int[] ans = new int[m]; + for (int i = 0; i < m; ++i) { + ans[i] = d.getOrDefault(nums1[i], -1); } return ans; } @@ -132,16 +132,21 @@ class Solution { public: vector nextGreaterElement(vector& nums1, vector& nums2) { stack stk; - unordered_map m; - for (int& v : nums2) { - while (!stk.empty() && stk.top() < v) { - m[stk.top()] = v; + unordered_map d; + ranges::reverse(nums2); + for (int x : nums2) { + while (!stk.empty() && stk.top() < x) { stk.pop(); } - stk.push(v); + if (!stk.empty()) { + d[x] = stk.top(); + } + stk.push(x); } vector ans; - for (int& v : nums1) ans.push_back(m.count(v) ? m[v] : -1); + for (int x : nums1) { + ans.push_back(d.contains(x) ? d[x] : -1); + } return ans; } }; @@ -150,25 +155,27 @@ public: #### Go ```go -func nextGreaterElement(nums1 []int, nums2 []int) []int { +func nextGreaterElement(nums1 []int, nums2 []int) (ans []int) { stk := []int{} - m := map[int]int{} - for _, v := range nums2 { - for len(stk) > 0 && stk[len(stk)-1] < v { - m[stk[len(stk)-1]] = v + d := map[int]int{} + for i := len(nums2) - 1; i >= 0; i-- { + x := nums2[i] + for len(stk) > 0 && stk[len(stk)-1] < x { stk = stk[:len(stk)-1] } - stk = append(stk, v) + if len(stk) > 0 { + d[x] = stk[len(stk)-1] + } + stk = append(stk, x) } - var ans []int - for _, v := range nums1 { - val, ok := m[v] - if !ok { - val = -1 + for _, x := range nums1 { + if v, ok := d[x]; ok { + ans = append(ans, v) + } else { + ans = append(ans, -1) } - ans = append(ans, val) } - return ans + return } ``` @@ -176,15 +183,16 @@ func nextGreaterElement(nums1 []int, nums2 []int) []int { ```ts function nextGreaterElement(nums1: number[], nums2: number[]): number[] { - const map = new Map(); - const stack: number[] = [Infinity]; - for (const num of nums2) { - while (num > stack[stack.length - 1]) { - map.set(stack.pop(), num); + const stk: number[] = []; + const d: Record = {}; + for (const x of nums2.reverse()) { + while (stk.length && stk.at(-1)! < x) { + stk.pop(); } - stack.push(num); + d[x] = stk.length ? stk.at(-1)! : -1; + stk.push(x); } - return nums1.map(num => map.get(num) || -1); + return nums1.map(x => d[x]); } ``` @@ -195,162 +203,26 @@ use std::collections::HashMap; impl Solution { pub fn next_greater_element(nums1: Vec, nums2: Vec) -> Vec { - let mut map = HashMap::new(); - let mut stack = Vec::new(); - for num in nums2 { - while num > *stack.last().unwrap_or(&i32::MAX) { - map.insert(stack.pop().unwrap(), num); - } - stack.push(num); - } - nums1 - .iter() - .map(|n| *map.get(n).unwrap_or(&-1)) - .collect::>() - } -} -``` - -#### JavaScript - -```js -/** - * @param {number[]} nums1 - * @param {number[]} nums2 - * @return {number[]} - */ -var nextGreaterElement = function (nums1, nums2) { - let stk = []; - let m = {}; - for (let v of nums2) { - while (stk && stk[stk.length - 1] < v) { - m[stk.pop()] = v; - } - stk.push(v); - } - return nums1.map(e => m[e] || -1); -}; -``` - - - - - - - -### 方法二 - - - -#### Python3 - -```python -class Solution: - def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: - m = {} - stk = [] - for v in nums2[::-1]: - while stk and stk[-1] <= v: - stk.pop() - if stk: - m[v] = stk[-1] - stk.append(v) - return [m.get(x, -1) for x in nums1] -``` - -#### Java - -```java -class Solution { - public int[] nextGreaterElement(int[] nums1, int[] nums2) { - Deque stk = new ArrayDeque<>(); - Map m = new HashMap<>(); - for (int i = nums2.length - 1; i >= 0; --i) { - while (!stk.isEmpty() && stk.peek() <= nums2[i]) { - stk.pop(); + let mut stk = Vec::new(); + let mut d = HashMap::new(); + for &x in nums2.iter().rev() { + while let Some(&top) = stk.last() { + if top <= x { + stk.pop(); + } else { + break; + } } - if (!stk.isEmpty()) { - m.put(nums2[i], stk.peek()); + if let Some(&top) = stk.last() { + d.insert(x, top); } - stk.push(nums2[i]); + stk.push(x); } - int n = nums1.length; - int[] ans = new int[n]; - for (int i = 0; i < n; ++i) { - ans[i] = m.getOrDefault(nums1[i], -1); - } - return ans; - } -} -``` - -#### C++ -```cpp -class Solution { -public: - vector nextGreaterElement(vector& nums1, vector& nums2) { - stack stk; - unordered_map m; - for (int i = nums2.size() - 1; ~i; --i) { - while (!stk.empty() && stk.top() <= nums2[i]) stk.pop(); - if (!stk.empty()) m[nums2[i]] = stk.top(); - stk.push(nums2[i]); - } - vector ans; - for (int& v : nums1) ans.push_back(m.count(v) ? m[v] : -1); - return ans; - } -}; -``` - -#### Go - -```go -func nextGreaterElement(nums1 []int, nums2 []int) []int { - stk := []int{} - m := map[int]int{} - for i := len(nums2) - 1; i >= 0; i-- { - for len(stk) > 0 && stk[len(stk)-1] <= nums2[i] { - stk = stk[:len(stk)-1] - } - if len(stk) > 0 { - m[nums2[i]] = stk[len(stk)-1] - } - stk = append(stk, nums2[i]) - } - var ans []int - for _, v := range nums1 { - val, ok := m[v] - if !ok { - val = -1 - } - ans = append(ans, val) - } - return ans -} -``` - -#### Rust - -```rust -impl Solution { - pub fn next_greater_element(nums1: Vec, nums2: Vec) -> Vec { nums1 - .iter() - .map(|target| { - let mut res = -1; - for num in nums2.iter().rev() { - if num == target { - break; - } - if num > target { - res = *num; - } - } - res - }) - .collect::>() + .into_iter() + .map(|x| *d.get(&x).unwrap_or(&-1)) + .collect() } } ``` @@ -364,18 +236,16 @@ impl Solution { * @return {number[]} */ var nextGreaterElement = function (nums1, nums2) { - let stk = []; - let m = {}; - for (let v of nums2.reverse()) { - while (stk && stk[stk.length - 1] <= v) { + const stk = []; + const d = {}; + for (const x of nums2.reverse()) { + while (stk.length && stk.at(-1) < x) { stk.pop(); } - if (stk) { - m[v] = stk[stk.length - 1]; - } - stk.push(v); + d[x] = stk.length ? stk.at(-1) : -1; + stk.push(x); } - return nums1.map(e => m[e] || -1); + return nums1.map(x => d[x]); }; ``` diff --git a/solution/0400-0499/0496.Next Greater Element I/README_EN.md b/solution/0400-0499/0496.Next Greater Element I/README_EN.md index 13c6f1706675b..333e574f3c536 100644 --- a/solution/0400-0499/0496.Next Greater Element I/README_EN.md +++ b/solution/0400-0499/0496.Next Greater Element I/README_EN.md @@ -68,7 +68,15 @@ tags: -### Solution 1 +### Solution 1: Monotonic Stack + +We can traverse the array $\textit{nums2}$ from right to left, maintaining a stack $\textit{stk}$ that is monotonically increasing from top to bottom. We use a hash table $\textit{d}$ to record the next greater element for each element. + +When we encounter an element $x$, if the stack is not empty and the top element of the stack is less than $x$, we keep popping the top elements until the stack is empty or the top element is greater than or equal to $x$. At this point, if the stack is not empty, the top element of the stack is the next greater element for $x$. Otherwise, $x$ has no next greater element. + +Finally, we traverse the array $\textit{nums1}$ and use the hash table $\textit{d}$ to get the answer. + +The time complexity is $O(m + n)$, and the space complexity is $O(n)$. Here, $m$ and $n$ are the lengths of the arrays $\textit{nums1}$ and $\textit{nums2}$, respectively. @@ -77,13 +85,15 @@ tags: ```python class Solution: def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: - m = {} stk = [] - for v in nums2: - while stk and stk[-1] < v: - m[stk.pop()] = v - stk.append(v) - return [m.get(v, -1) for v in nums1] + d = {} + for x in nums2[::-1]: + while stk and stk[-1] < x: + stk.pop() + if stk: + d[x] = stk[-1] + stk.append(x) + return [d.get(x, -1) for x in nums1] ``` #### Java @@ -92,17 +102,21 @@ class Solution: class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { Deque stk = new ArrayDeque<>(); - Map m = new HashMap<>(); - for (int v : nums2) { - while (!stk.isEmpty() && stk.peek() < v) { - m.put(stk.pop(), v); + int m = nums1.length, n = nums2.length; + Map d = new HashMap(n); + for (int i = n - 1; i >= 0; --i) { + int x = nums2[i]; + while (!stk.isEmpty() && stk.peek() < x) { + stk.pop(); } - stk.push(v); + if (!stk.isEmpty()) { + d.put(x, stk.peek()); + } + stk.push(x); } - int n = nums1.length; - int[] ans = new int[n]; - for (int i = 0; i < n; ++i) { - ans[i] = m.getOrDefault(nums1[i], -1); + int[] ans = new int[m]; + for (int i = 0; i < m; ++i) { + ans[i] = d.getOrDefault(nums1[i], -1); } return ans; } @@ -116,16 +130,21 @@ class Solution { public: vector nextGreaterElement(vector& nums1, vector& nums2) { stack stk; - unordered_map m; - for (int& v : nums2) { - while (!stk.empty() && stk.top() < v) { - m[stk.top()] = v; + unordered_map d; + ranges::reverse(nums2); + for (int x : nums2) { + while (!stk.empty() && stk.top() < x) { stk.pop(); } - stk.push(v); + if (!stk.empty()) { + d[x] = stk.top(); + } + stk.push(x); } vector ans; - for (int& v : nums1) ans.push_back(m.count(v) ? m[v] : -1); + for (int x : nums1) { + ans.push_back(d.contains(x) ? d[x] : -1); + } return ans; } }; @@ -134,25 +153,27 @@ public: #### Go ```go -func nextGreaterElement(nums1 []int, nums2 []int) []int { +func nextGreaterElement(nums1 []int, nums2 []int) (ans []int) { stk := []int{} - m := map[int]int{} - for _, v := range nums2 { - for len(stk) > 0 && stk[len(stk)-1] < v { - m[stk[len(stk)-1]] = v + d := map[int]int{} + for i := len(nums2) - 1; i >= 0; i-- { + x := nums2[i] + for len(stk) > 0 && stk[len(stk)-1] < x { stk = stk[:len(stk)-1] } - stk = append(stk, v) + if len(stk) > 0 { + d[x] = stk[len(stk)-1] + } + stk = append(stk, x) } - var ans []int - for _, v := range nums1 { - val, ok := m[v] - if !ok { - val = -1 + for _, x := range nums1 { + if v, ok := d[x]; ok { + ans = append(ans, v) + } else { + ans = append(ans, -1) } - ans = append(ans, val) } - return ans + return } ``` @@ -160,15 +181,16 @@ func nextGreaterElement(nums1 []int, nums2 []int) []int { ```ts function nextGreaterElement(nums1: number[], nums2: number[]): number[] { - const map = new Map(); - const stack: number[] = [Infinity]; - for (const num of nums2) { - while (num > stack[stack.length - 1]) { - map.set(stack.pop(), num); + const stk: number[] = []; + const d: Record = {}; + for (const x of nums2.reverse()) { + while (stk.length && stk.at(-1)! < x) { + stk.pop(); } - stack.push(num); + d[x] = stk.length ? stk.at(-1)! : -1; + stk.push(x); } - return nums1.map(num => map.get(num) || -1); + return nums1.map(x => d[x]); } ``` @@ -179,162 +201,26 @@ use std::collections::HashMap; impl Solution { pub fn next_greater_element(nums1: Vec, nums2: Vec) -> Vec { - let mut map = HashMap::new(); - let mut stack = Vec::new(); - for num in nums2 { - while num > *stack.last().unwrap_or(&i32::MAX) { - map.insert(stack.pop().unwrap(), num); - } - stack.push(num); - } - nums1 - .iter() - .map(|n| *map.get(n).unwrap_or(&-1)) - .collect::>() - } -} -``` - -#### JavaScript - -```js -/** - * @param {number[]} nums1 - * @param {number[]} nums2 - * @return {number[]} - */ -var nextGreaterElement = function (nums1, nums2) { - let stk = []; - let m = {}; - for (let v of nums2) { - while (stk && stk[stk.length - 1] < v) { - m[stk.pop()] = v; - } - stk.push(v); - } - return nums1.map(e => m[e] || -1); -}; -``` - - - - - - - -### Solution 2 - - - -#### Python3 - -```python -class Solution: - def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: - m = {} - stk = [] - for v in nums2[::-1]: - while stk and stk[-1] <= v: - stk.pop() - if stk: - m[v] = stk[-1] - stk.append(v) - return [m.get(x, -1) for x in nums1] -``` - -#### Java - -```java -class Solution { - public int[] nextGreaterElement(int[] nums1, int[] nums2) { - Deque stk = new ArrayDeque<>(); - Map m = new HashMap<>(); - for (int i = nums2.length - 1; i >= 0; --i) { - while (!stk.isEmpty() && stk.peek() <= nums2[i]) { - stk.pop(); + let mut stk = Vec::new(); + let mut d = HashMap::new(); + for &x in nums2.iter().rev() { + while let Some(&top) = stk.last() { + if top <= x { + stk.pop(); + } else { + break; + } } - if (!stk.isEmpty()) { - m.put(nums2[i], stk.peek()); + if let Some(&top) = stk.last() { + d.insert(x, top); } - stk.push(nums2[i]); - } - int n = nums1.length; - int[] ans = new int[n]; - for (int i = 0; i < n; ++i) { - ans[i] = m.getOrDefault(nums1[i], -1); - } - return ans; - } -} -``` - -#### C++ - -```cpp -class Solution { -public: - vector nextGreaterElement(vector& nums1, vector& nums2) { - stack stk; - unordered_map m; - for (int i = nums2.size() - 1; ~i; --i) { - while (!stk.empty() && stk.top() <= nums2[i]) stk.pop(); - if (!stk.empty()) m[nums2[i]] = stk.top(); - stk.push(nums2[i]); + stk.push(x); } - vector ans; - for (int& v : nums1) ans.push_back(m.count(v) ? m[v] : -1); - return ans; - } -}; -``` - -#### Go - -```go -func nextGreaterElement(nums1 []int, nums2 []int) []int { - stk := []int{} - m := map[int]int{} - for i := len(nums2) - 1; i >= 0; i-- { - for len(stk) > 0 && stk[len(stk)-1] <= nums2[i] { - stk = stk[:len(stk)-1] - } - if len(stk) > 0 { - m[nums2[i]] = stk[len(stk)-1] - } - stk = append(stk, nums2[i]) - } - var ans []int - for _, v := range nums1 { - val, ok := m[v] - if !ok { - val = -1 - } - ans = append(ans, val) - } - return ans -} -``` -#### Rust - -```rust -impl Solution { - pub fn next_greater_element(nums1: Vec, nums2: Vec) -> Vec { nums1 - .iter() - .map(|target| { - let mut res = -1; - for num in nums2.iter().rev() { - if num == target { - break; - } - if num > target { - res = *num; - } - } - res - }) - .collect::>() + .into_iter() + .map(|x| *d.get(&x).unwrap_or(&-1)) + .collect() } } ``` @@ -348,18 +234,16 @@ impl Solution { * @return {number[]} */ var nextGreaterElement = function (nums1, nums2) { - let stk = []; - let m = {}; - for (let v of nums2.reverse()) { - while (stk && stk[stk.length - 1] <= v) { + const stk = []; + const d = {}; + for (const x of nums2.reverse()) { + while (stk.length && stk.at(-1) < x) { stk.pop(); } - if (stk) { - m[v] = stk[stk.length - 1]; - } - stk.push(v); + d[x] = stk.length ? stk.at(-1) : -1; + stk.push(x); } - return nums1.map(e => m[e] || -1); + return nums1.map(x => d[x]); }; ``` diff --git a/solution/0400-0499/0496.Next Greater Element I/Solution.cpp b/solution/0400-0499/0496.Next Greater Element I/Solution.cpp index 5f7136337d3d2..9683cba75971e 100644 --- a/solution/0400-0499/0496.Next Greater Element I/Solution.cpp +++ b/solution/0400-0499/0496.Next Greater Element I/Solution.cpp @@ -2,16 +2,21 @@ class Solution { public: vector nextGreaterElement(vector& nums1, vector& nums2) { stack stk; - unordered_map m; - for (int& v : nums2) { - while (!stk.empty() && stk.top() < v) { - m[stk.top()] = v; + unordered_map d; + ranges::reverse(nums2); + for (int x : nums2) { + while (!stk.empty() && stk.top() < x) { stk.pop(); } - stk.push(v); + if (!stk.empty()) { + d[x] = stk.top(); + } + stk.push(x); } vector ans; - for (int& v : nums1) ans.push_back(m.count(v) ? m[v] : -1); + for (int x : nums1) { + ans.push_back(d.contains(x) ? d[x] : -1); + } return ans; } -}; \ No newline at end of file +}; diff --git a/solution/0400-0499/0496.Next Greater Element I/Solution.go b/solution/0400-0499/0496.Next Greater Element I/Solution.go index 7e8a40807cf0f..603aa300050a6 100644 --- a/solution/0400-0499/0496.Next Greater Element I/Solution.go +++ b/solution/0400-0499/0496.Next Greater Element I/Solution.go @@ -1,20 +1,22 @@ -func nextGreaterElement(nums1 []int, nums2 []int) []int { +func nextGreaterElement(nums1 []int, nums2 []int) (ans []int) { stk := []int{} - m := map[int]int{} - for _, v := range nums2 { - for len(stk) > 0 && stk[len(stk)-1] < v { - m[stk[len(stk)-1]] = v + d := map[int]int{} + for i := len(nums2) - 1; i >= 0; i-- { + x := nums2[i] + for len(stk) > 0 && stk[len(stk)-1] < x { stk = stk[:len(stk)-1] } - stk = append(stk, v) + if len(stk) > 0 { + d[x] = stk[len(stk)-1] + } + stk = append(stk, x) } - var ans []int - for _, v := range nums1 { - val, ok := m[v] - if !ok { - val = -1 + for _, x := range nums1 { + if v, ok := d[x]; ok { + ans = append(ans, v) + } else { + ans = append(ans, -1) } - ans = append(ans, val) } - return ans -} \ No newline at end of file + return +} diff --git a/solution/0400-0499/0496.Next Greater Element I/Solution.java b/solution/0400-0499/0496.Next Greater Element I/Solution.java index ee2f5deb0eef6..bcb89a46277e3 100644 --- a/solution/0400-0499/0496.Next Greater Element I/Solution.java +++ b/solution/0400-0499/0496.Next Greater Element I/Solution.java @@ -1,18 +1,22 @@ class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { Deque stk = new ArrayDeque<>(); - Map m = new HashMap<>(); - for (int v : nums2) { - while (!stk.isEmpty() && stk.peek() < v) { - m.put(stk.pop(), v); + int m = nums1.length, n = nums2.length; + Map d = new HashMap(n); + for (int i = n - 1; i >= 0; --i) { + int x = nums2[i]; + while (!stk.isEmpty() && stk.peek() < x) { + stk.pop(); } - stk.push(v); + if (!stk.isEmpty()) { + d.put(x, stk.peek()); + } + stk.push(x); } - int n = nums1.length; - int[] ans = new int[n]; - for (int i = 0; i < n; ++i) { - ans[i] = m.getOrDefault(nums1[i], -1); + int[] ans = new int[m]; + for (int i = 0; i < m; ++i) { + ans[i] = d.getOrDefault(nums1[i], -1); } return ans; } -} \ No newline at end of file +} diff --git a/solution/0400-0499/0496.Next Greater Element I/Solution.js b/solution/0400-0499/0496.Next Greater Element I/Solution.js index f25d539e765ce..36fc760c93de4 100644 --- a/solution/0400-0499/0496.Next Greater Element I/Solution.js +++ b/solution/0400-0499/0496.Next Greater Element I/Solution.js @@ -4,13 +4,14 @@ * @return {number[]} */ var nextGreaterElement = function (nums1, nums2) { - let stk = []; - let m = {}; - for (let v of nums2) { - while (stk && stk[stk.length - 1] < v) { - m[stk.pop()] = v; + const stk = []; + const d = {}; + for (const x of nums2.reverse()) { + while (stk.length && stk.at(-1) < x) { + stk.pop(); } - stk.push(v); + d[x] = stk.length ? stk.at(-1) : -1; + stk.push(x); } - return nums1.map(e => m[e] || -1); + return nums1.map(x => d[x]); }; diff --git a/solution/0400-0499/0496.Next Greater Element I/Solution.py b/solution/0400-0499/0496.Next Greater Element I/Solution.py index 44040ba42ebc7..ebd8a65e04f9a 100644 --- a/solution/0400-0499/0496.Next Greater Element I/Solution.py +++ b/solution/0400-0499/0496.Next Greater Element I/Solution.py @@ -1,9 +1,11 @@ class Solution: def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: - m = {} stk = [] - for v in nums2: - while stk and stk[-1] < v: - m[stk.pop()] = v - stk.append(v) - return [m.get(v, -1) for v in nums1] + d = {} + for x in nums2[::-1]: + while stk and stk[-1] < x: + stk.pop() + if stk: + d[x] = stk[-1] + stk.append(x) + return [d.get(x, -1) for x in nums1] diff --git a/solution/0400-0499/0496.Next Greater Element I/Solution.rs b/solution/0400-0499/0496.Next Greater Element I/Solution.rs index 93580e00fd289..57b025735850b 100644 --- a/solution/0400-0499/0496.Next Greater Element I/Solution.rs +++ b/solution/0400-0499/0496.Next Greater Element I/Solution.rs @@ -2,17 +2,25 @@ use std::collections::HashMap; impl Solution { pub fn next_greater_element(nums1: Vec, nums2: Vec) -> Vec { - let mut map = HashMap::new(); - let mut stack = Vec::new(); - for num in nums2 { - while num > *stack.last().unwrap_or(&i32::MAX) { - map.insert(stack.pop().unwrap(), num); + let mut stk = Vec::new(); + let mut d = HashMap::new(); + for &x in nums2.iter().rev() { + while let Some(&top) = stk.last() { + if top <= x { + stk.pop(); + } else { + break; + } } - stack.push(num); + if let Some(&top) = stk.last() { + d.insert(x, top); + } + stk.push(x); } + nums1 - .iter() - .map(|n| *map.get(n).unwrap_or(&-1)) - .collect::>() + .into_iter() + .map(|x| *d.get(&x).unwrap_or(&-1)) + .collect() } } diff --git a/solution/0400-0499/0496.Next Greater Element I/Solution.ts b/solution/0400-0499/0496.Next Greater Element I/Solution.ts index 6678ad8521b66..c77c1d2bb4240 100644 --- a/solution/0400-0499/0496.Next Greater Element I/Solution.ts +++ b/solution/0400-0499/0496.Next Greater Element I/Solution.ts @@ -1,11 +1,12 @@ function nextGreaterElement(nums1: number[], nums2: number[]): number[] { - const map = new Map(); - const stack: number[] = [Infinity]; - for (const num of nums2) { - while (num > stack[stack.length - 1]) { - map.set(stack.pop(), num); + const stk: number[] = []; + const d: Record = {}; + for (const x of nums2.reverse()) { + while (stk.length && stk.at(-1)! < x) { + stk.pop(); } - stack.push(num); + d[x] = stk.length ? stk.at(-1)! : -1; + stk.push(x); } - return nums1.map(num => map.get(num) || -1); + return nums1.map(x => d[x]); } diff --git a/solution/0400-0499/0496.Next Greater Element I/Solution2.cpp b/solution/0400-0499/0496.Next Greater Element I/Solution2.cpp deleted file mode 100644 index 8fd148a48d791..0000000000000 --- a/solution/0400-0499/0496.Next Greater Element I/Solution2.cpp +++ /dev/null @@ -1,15 +0,0 @@ -class Solution { -public: - vector nextGreaterElement(vector& nums1, vector& nums2) { - stack stk; - unordered_map m; - for (int i = nums2.size() - 1; ~i; --i) { - while (!stk.empty() && stk.top() <= nums2[i]) stk.pop(); - if (!stk.empty()) m[nums2[i]] = stk.top(); - stk.push(nums2[i]); - } - vector ans; - for (int& v : nums1) ans.push_back(m.count(v) ? m[v] : -1); - return ans; - } -}; \ No newline at end of file diff --git a/solution/0400-0499/0496.Next Greater Element I/Solution2.go b/solution/0400-0499/0496.Next Greater Element I/Solution2.go deleted file mode 100644 index e4c138babc9d7..0000000000000 --- a/solution/0400-0499/0496.Next Greater Element I/Solution2.go +++ /dev/null @@ -1,22 +0,0 @@ -func nextGreaterElement(nums1 []int, nums2 []int) []int { - stk := []int{} - m := map[int]int{} - for i := len(nums2) - 1; i >= 0; i-- { - for len(stk) > 0 && stk[len(stk)-1] <= nums2[i] { - stk = stk[:len(stk)-1] - } - if len(stk) > 0 { - m[nums2[i]] = stk[len(stk)-1] - } - stk = append(stk, nums2[i]) - } - var ans []int - for _, v := range nums1 { - val, ok := m[v] - if !ok { - val = -1 - } - ans = append(ans, val) - } - return ans -} \ No newline at end of file diff --git a/solution/0400-0499/0496.Next Greater Element I/Solution2.java b/solution/0400-0499/0496.Next Greater Element I/Solution2.java deleted file mode 100644 index fd585b1ad1a5b..0000000000000 --- a/solution/0400-0499/0496.Next Greater Element I/Solution2.java +++ /dev/null @@ -1,21 +0,0 @@ -class Solution { - public int[] nextGreaterElement(int[] nums1, int[] nums2) { - Deque stk = new ArrayDeque<>(); - Map m = new HashMap<>(); - for (int i = nums2.length - 1; i >= 0; --i) { - while (!stk.isEmpty() && stk.peek() <= nums2[i]) { - stk.pop(); - } - if (!stk.isEmpty()) { - m.put(nums2[i], stk.peek()); - } - stk.push(nums2[i]); - } - int n = nums1.length; - int[] ans = new int[n]; - for (int i = 0; i < n; ++i) { - ans[i] = m.getOrDefault(nums1[i], -1); - } - return ans; - } -} \ No newline at end of file diff --git a/solution/0400-0499/0496.Next Greater Element I/Solution2.js b/solution/0400-0499/0496.Next Greater Element I/Solution2.js deleted file mode 100644 index 7fd49e49310dd..0000000000000 --- a/solution/0400-0499/0496.Next Greater Element I/Solution2.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @param {number[]} nums1 - * @param {number[]} nums2 - * @return {number[]} - */ -var nextGreaterElement = function (nums1, nums2) { - let stk = []; - let m = {}; - for (let v of nums2.reverse()) { - while (stk && stk[stk.length - 1] <= v) { - stk.pop(); - } - if (stk) { - m[v] = stk[stk.length - 1]; - } - stk.push(v); - } - return nums1.map(e => m[e] || -1); -}; diff --git a/solution/0400-0499/0496.Next Greater Element I/Solution2.py b/solution/0400-0499/0496.Next Greater Element I/Solution2.py deleted file mode 100644 index ce7da164957c2..0000000000000 --- a/solution/0400-0499/0496.Next Greater Element I/Solution2.py +++ /dev/null @@ -1,11 +0,0 @@ -class Solution: - def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: - m = {} - stk = [] - for v in nums2[::-1]: - while stk and stk[-1] <= v: - stk.pop() - if stk: - m[v] = stk[-1] - stk.append(v) - return [m.get(x, -1) for x in nums1] diff --git a/solution/0400-0499/0496.Next Greater Element I/Solution2.rs b/solution/0400-0499/0496.Next Greater Element I/Solution2.rs deleted file mode 100644 index 8ac2d1be7f398..0000000000000 --- a/solution/0400-0499/0496.Next Greater Element I/Solution2.rs +++ /dev/null @@ -1,19 +0,0 @@ -impl Solution { - pub fn next_greater_element(nums1: Vec, nums2: Vec) -> Vec { - nums1 - .iter() - .map(|target| { - let mut res = -1; - for num in nums2.iter().rev() { - if num == target { - break; - } - if num > target { - res = *num; - } - } - res - }) - .collect::>() - } -}