From 8594ff9d64ef3ab609fd6b98cc6e1568cba7f6b0 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sat, 11 May 2024 12:49:21 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.2197 No.2197.Replace Non-Coprime Numbers in Array --- .../README.md | 138 ++++++++++++++++++ .../README_EN.md | 138 ++++++++++++++++++ .../Solution.cpp | 20 +++ .../Solution.go | 24 +++ .../Solution.java | 26 ++++ .../Solution.py | 13 ++ .../Solution.ts | 24 +++ 7 files changed, 383 insertions(+) create mode 100644 solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.cpp create mode 100644 solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.go create mode 100644 solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.java create mode 100644 solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.py create mode 100644 solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.ts diff --git a/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/README.md b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/README.md index 3f1778b7f8fad..63ff808a58b5c 100644 --- a/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/README.md +++ b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/README.md @@ -66,4 +66,142 @@ ## 解法 +### 方法一:栈 + +如果存在三个相邻的数 $x$, $y$, $z$ 可以进行合并,那么我们先合并 $x$ 和 $y$,再合并 $z$ 的结果,与先合并 $y$ 和 $z$,再合并 $x$ 的结果是一样的,结果均为 $\text{LCM}(x, y, z)$。 + +因此,我们可以总是优先合并左侧相邻的数,再将合并后的结果与右侧相邻的数进行合并。 + +我们使用一个栈来模拟这个过程,遍历数组,对于每个数,我们将其入栈,然后不断检查栈顶的两个数是否互质,如果不互质,我们将这两个数出栈,然后将它们的最小公倍数入栈,直到栈顶的两个数互质,或者栈中元素小于两个。 + +最后栈中的元素即为最终结果。 + +时间复杂度 $O(n \times \log M)$,空间复杂度 $O(n)$。其中 $M$ 为数组中的最大值。 + + + +```python +class Solution: + def replaceNonCoprimes(self, nums: List[int]) -> List[int]: + stk = [] + for x in nums: + stk.append(x) + while len(stk) > 1: + x, y = stk[-2:] + g = gcd(x, y) + if g == 1: + break + stk.pop() + stk[-1] = x * y // g + return stk +``` + +```java +class Solution { + public List replaceNonCoprimes(int[] nums) { + List stk = new ArrayList<>(); + for (int x : nums) { + stk.add(x); + while (stk.size() > 1) { + x = stk.get(stk.size() - 1); + int y = stk.get(stk.size() - 2); + int g = gcd(x, y); + if (g == 1) { + break; + } + stk.remove(stk.size() - 1); + stk.set(stk.size() - 1, (int) ((long) x * y / g)); + } + } + return stk; + } + + private int gcd(int a, int b) { + if (b == 0) { + return a; + } + return gcd(b, a % b); + } +} +``` + +```cpp +class Solution { +public: + vector replaceNonCoprimes(vector& nums) { + vector stk; + for (int x : nums) { + stk.push_back(x); + while (stk.size() > 1) { + x = stk.back(); + int y = stk[stk.size() - 2]; + int g = __gcd(x, y); + if (g == 1) { + break; + } + stk.pop_back(); + stk.back() = 1LL * x * y / g; + } + } + return stk; + } +}; +``` + +```go +func replaceNonCoprimes(nums []int) []int { + stk := []int{} + for _, x := range nums { + stk = append(stk, x) + for len(stk) > 1 { + x = stk[len(stk)-1] + y := stk[len(stk)-2] + g := gcd(x, y) + if g == 1 { + break + } + stk = stk[:len(stk)-1] + stk[len(stk)-1] = x * y / g + } + } + return stk +} + +func gcd(a, b int) int { + if b == 0 { + return a + } + return gcd(b, a%b) +} +``` + +```ts +function replaceNonCoprimes(nums: number[]): number[] { + const gcd = (a: number, b: number): number => { + if (b === 0) { + return a; + } + return gcd(b, a % b); + }; + const stk: number[] = []; + for (let x of nums) { + stk.push(x); + while (stk.length > 1) { + x = stk.at(-1)!; + const y = stk.at(-2)!; + const g = gcd(x, y); + if (g === 1) { + break; + } + stk.pop(); + stk.pop(); + stk.push(((x * y) / g) | 0); + } + } + return stk; +} +``` + + + diff --git a/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/README_EN.md b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/README_EN.md index cab468402e307..926d5e45a566b 100644 --- a/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/README_EN.md +++ b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/README_EN.md @@ -62,4 +62,142 @@ Note that there are other ways to obtain the same resultant array. ## Solutions +### Solution 1: Stack + +If there exist three adjacent numbers $x$, $y$, $z$ that can be merged, then the result of first merging $x$ and $y$, then merging $z$, is the same as the result of first merging $y$ and $z$, then merging $x$. Both results are $\text{LCM}(x, y, z)$. + +Therefore, we can always prefer to merge the adjacent numbers on the left, and then merge the result with the adjacent number on the right. + +We use a stack to simulate this process. We traverse the array, and for each number, we push it into the stack. Then we continuously check whether the top two numbers of the stack are coprime. If they are not coprime, we pop these two numbers out of the stack, and then push their least common multiple into the stack, until the top two numbers of the stack are coprime, or there are less than two elements in the stack. + +The final elements in the stack are the final result. + +The time complexity is $O(n \times \log M)$, and the space complexity is $O(n)$. Where $M$ is the maximum value in the array. + + + +```python +class Solution: + def replaceNonCoprimes(self, nums: List[int]) -> List[int]: + stk = [] + for x in nums: + stk.append(x) + while len(stk) > 1: + x, y = stk[-2:] + g = gcd(x, y) + if g == 1: + break + stk.pop() + stk[-1] = x * y // g + return stk +``` + +```java +class Solution { + public List replaceNonCoprimes(int[] nums) { + List stk = new ArrayList<>(); + for (int x : nums) { + stk.add(x); + while (stk.size() > 1) { + x = stk.get(stk.size() - 1); + int y = stk.get(stk.size() - 2); + int g = gcd(x, y); + if (g == 1) { + break; + } + stk.remove(stk.size() - 1); + stk.set(stk.size() - 1, (int) ((long) x * y / g)); + } + } + return stk; + } + + private int gcd(int a, int b) { + if (b == 0) { + return a; + } + return gcd(b, a % b); + } +} +``` + +```cpp +class Solution { +public: + vector replaceNonCoprimes(vector& nums) { + vector stk; + for (int x : nums) { + stk.push_back(x); + while (stk.size() > 1) { + x = stk.back(); + int y = stk[stk.size() - 2]; + int g = __gcd(x, y); + if (g == 1) { + break; + } + stk.pop_back(); + stk.back() = 1LL * x * y / g; + } + } + return stk; + } +}; +``` + +```go +func replaceNonCoprimes(nums []int) []int { + stk := []int{} + for _, x := range nums { + stk = append(stk, x) + for len(stk) > 1 { + x = stk[len(stk)-1] + y := stk[len(stk)-2] + g := gcd(x, y) + if g == 1 { + break + } + stk = stk[:len(stk)-1] + stk[len(stk)-1] = x * y / g + } + } + return stk +} + +func gcd(a, b int) int { + if b == 0 { + return a + } + return gcd(b, a%b) +} +``` + +```ts +function replaceNonCoprimes(nums: number[]): number[] { + const gcd = (a: number, b: number): number => { + if (b === 0) { + return a; + } + return gcd(b, a % b); + }; + const stk: number[] = []; + for (let x of nums) { + stk.push(x); + while (stk.length > 1) { + x = stk.at(-1)!; + const y = stk.at(-2)!; + const g = gcd(x, y); + if (g === 1) { + break; + } + stk.pop(); + stk.pop(); + stk.push(((x * y) / g) | 0); + } + } + return stk; +} +``` + + + diff --git a/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.cpp b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.cpp new file mode 100644 index 0000000000000..32f0862b9805c --- /dev/null +++ b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.cpp @@ -0,0 +1,20 @@ +class Solution { +public: + vector replaceNonCoprimes(vector& nums) { + vector stk; + for (int x : nums) { + stk.push_back(x); + while (stk.size() > 1) { + x = stk.back(); + int y = stk[stk.size() - 2]; + int g = __gcd(x, y); + if (g == 1) { + break; + } + stk.pop_back(); + stk.back() = 1LL * x * y / g; + } + } + return stk; + } +}; \ No newline at end of file diff --git a/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.go b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.go new file mode 100644 index 0000000000000..e4f5ec5d75321 --- /dev/null +++ b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.go @@ -0,0 +1,24 @@ +func replaceNonCoprimes(nums []int) []int { + stk := []int{} + for _, x := range nums { + stk = append(stk, x) + for len(stk) > 1 { + x = stk[len(stk)-1] + y := stk[len(stk)-2] + g := gcd(x, y) + if g == 1 { + break + } + stk = stk[:len(stk)-1] + stk[len(stk)-1] = x * y / g + } + } + return stk +} + +func gcd(a, b int) int { + if b == 0 { + return a + } + return gcd(b, a%b) +} \ No newline at end of file diff --git a/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.java b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.java new file mode 100644 index 0000000000000..2b5affbc8d320 --- /dev/null +++ b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.java @@ -0,0 +1,26 @@ +class Solution { + public List replaceNonCoprimes(int[] nums) { + List stk = new ArrayList<>(); + for (int x : nums) { + stk.add(x); + while (stk.size() > 1) { + x = stk.get(stk.size() - 1); + int y = stk.get(stk.size() - 2); + int g = gcd(x, y); + if (g == 1) { + break; + } + stk.remove(stk.size() - 1); + stk.set(stk.size() - 1, (int) ((long) x * y / g)); + } + } + return stk; + } + + private int gcd(int a, int b) { + if (b == 0) { + return a; + } + return gcd(b, a % b); + } +} \ No newline at end of file diff --git a/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.py b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.py new file mode 100644 index 0000000000000..b4e3b0c599c5e --- /dev/null +++ b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.py @@ -0,0 +1,13 @@ +class Solution: + def replaceNonCoprimes(self, nums: List[int]) -> List[int]: + stk = [] + for x in nums: + stk.append(x) + while len(stk) > 1: + x, y = stk[-2:] + g = gcd(x, y) + if g == 1: + break + stk.pop() + stk[-1] = x * y // g + return stk diff --git a/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.ts b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.ts new file mode 100644 index 0000000000000..b6ec9ecb34597 --- /dev/null +++ b/solution/2100-2199/2197.Replace Non-Coprime Numbers in Array/Solution.ts @@ -0,0 +1,24 @@ +function replaceNonCoprimes(nums: number[]): number[] { + const gcd = (a: number, b: number): number => { + if (b === 0) { + return a; + } + return gcd(b, a % b); + }; + const stk: number[] = []; + for (let x of nums) { + stk.push(x); + while (stk.length > 1) { + x = stk.at(-1)!; + const y = stk.at(-2)!; + const g = gcd(x, y); + if (g === 1) { + break; + } + stk.pop(); + stk.pop(); + stk.push(((x * y) / g) | 0); + } + } + return stk; +}