Skip to content

Commit a68d695

Browse files
authored
feat: add solutions to lc problem: No.3326 (#3657)
No.3326.Minimum Division Operations to Make Array Non Decreasing
1 parent b6b5db0 commit a68d695

File tree

7 files changed

+414
-8
lines changed

7 files changed

+414
-8
lines changed

solution/3300-3399/3326.Minimum Division Operations to Make Array Non Decreasing/README.md

+143-4
Original file line numberDiff line numberDiff line change
@@ -70,32 +70,171 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3326.Mi
7070

7171
<!-- solution:start -->
7272

73-
### 方法一
73+
### 方法一:预处理 + 贪心
74+
75+
根据题目描述,
76+
77+
如果整数 $x$ 是质数,那么它的最大真因数是 $1$,那么 $x / 1 = x$,即 $x$ 不能再被除了;
78+
79+
如果整数 $x$ 不是质数,我们假设 $x$ 的最大真因数为 $y$,那么 $x / y$ 一定是质数,因此,我们寻找最小质数 $\textit{lpf}[x]$,使得 $x \bmod \textit{lpf}[x] = 0$,使得 $x$ 变成 $\textit{lpf}[x]$,此时无法再被除了。
80+
81+
因此,我们可以预处理出 $1$ 到 $10^6$ 的每个整数的最小质因数,然后从右往左遍历数组,如果当前元素大于下一个元素,我们将当前元素变为它的最小质因数,如果当前元素变为它的最小质因数后,仍然大于下一个元素,说明无法将数组变成非递减的,返回 $-1$。否则,操作次数加一。继续遍历,直到遍历完整个数组。
82+
83+
预处理的时间复杂度为 $O(M \times \log \log M)$,其中 $M = 10^6$,遍历数组的时间复杂度为 $O(n)$,其中 $n$ 为数组的长度。空间复杂度为 $O(M)$。
7484

7585
<!-- tabs:start -->
7686

7787
#### Python3
7888

7989
```python
80-
90+
mx = 10**6 + 1
91+
lpf = [0] * (mx + 1)
92+
for i in range(2, mx + 1):
93+
if lpf[i] == 0:
94+
for j in range(i, mx + 1, i):
95+
if lpf[j] == 0:
96+
lpf[j] = i
97+
98+
99+
class Solution:
100+
def minOperations(self, nums: List[int]) -> int:
101+
ans = 0
102+
for i in range(len(nums) - 2, -1, -1):
103+
if nums[i] > nums[i + 1]:
104+
nums[i] = lpf[nums[i]]
105+
if nums[i] > nums[i + 1]:
106+
return -1
107+
ans += 1
108+
return ans
81109
```
82110

83111
#### Java
84112

85113
```java
86-
114+
class Solution {
115+
private static final int MX = (int) 1e6 + 1;
116+
private static final int[] LPF = new int[MX + 1];
117+
static {
118+
for (int i = 2; i <= MX; ++i) {
119+
for (int j = i; j <= MX; j += i) {
120+
if (LPF[j] == 0) {
121+
LPF[j] = i;
122+
}
123+
}
124+
}
125+
}
126+
public int minOperations(int[] nums) {
127+
int ans = 0;
128+
for (int i = nums.length - 2; i >= 0; i--) {
129+
if (nums[i] > nums[i + 1]) {
130+
nums[i] = LPF[nums[i]];
131+
if (nums[i] > nums[i + 1]) {
132+
return -1;
133+
}
134+
ans++;
135+
}
136+
}
137+
return ans;
138+
}
139+
}
87140
```
88141

89142
#### C++
90143

91144
```cpp
92-
145+
const int MX = 1e6;
146+
int LPF[MX + 1];
147+
148+
auto init = [] {
149+
for (int i = 2; i <= MX; i++) {
150+
if (LPF[i] == 0) {
151+
for (int j = i; j <= MX; j += i) {
152+
if (LPF[j] == 0) {
153+
LPF[j] = i;
154+
}
155+
}
156+
}
157+
}
158+
return 0;
159+
}();
160+
161+
class Solution {
162+
public:
163+
int minOperations(vector<int>& nums) {
164+
int ans = 0;
165+
for (int i = nums.size() - 2; i >= 0; i--) {
166+
if (nums[i] > nums[i + 1]) {
167+
nums[i] = LPF[nums[i]];
168+
if (nums[i] > nums[i + 1]) {
169+
return -1;
170+
}
171+
ans++;
172+
}
173+
}
174+
return ans;
175+
}
176+
};
93177
```
94178
95179
#### Go
96180
97181
```go
182+
const mx int = 1e6
183+
184+
var lpf = [mx + 1]int{}
185+
186+
func init() {
187+
for i := 2; i <= mx; i++ {
188+
if lpf[i] == 0 {
189+
for j := i; j <= mx; j += i {
190+
if lpf[j] == 0 {
191+
lpf[j] = i
192+
}
193+
}
194+
}
195+
}
196+
}
197+
198+
func minOperations(nums []int) (ans int) {
199+
for i := len(nums) - 2; i >= 0; i-- {
200+
if nums[i] > nums[i+1] {
201+
nums[i] = lpf[nums[i]]
202+
if nums[i] > nums[i+1] {
203+
return -1
204+
}
205+
ans++
206+
}
207+
}
208+
return
209+
}
210+
```
98211

212+
#### TypeScript
213+
214+
```ts
215+
const mx = 10 ** 6;
216+
const lpf = Array(mx + 1).fill(0);
217+
for (let i = 2; i <= mx; ++i) {
218+
for (let j = i; j <= mx; j += i) {
219+
if (lpf[j] === 0) {
220+
lpf[j] = i;
221+
}
222+
}
223+
}
224+
225+
function minOperations(nums: number[]): number {
226+
let ans = 0;
227+
for (let i = nums.length - 2; ~i; --i) {
228+
if (nums[i] > nums[i + 1]) {
229+
nums[i] = lpf[nums[i]];
230+
if (nums[i] > nums[i + 1]) {
231+
return -1;
232+
}
233+
++ans;
234+
}
235+
}
236+
return ans;
237+
}
99238
```
100239

101240
<!-- tabs:end -->

solution/3300-3399/3326.Minimum Division Operations to Make Array Non Decreasing/README_EN.md

+143-4
Original file line numberDiff line numberDiff line change
@@ -67,32 +67,171 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3326.Mi
6767

6868
<!-- solution:start -->
6969

70-
### Solution 1
70+
### Solution 1: Preprocessing + Greedy
71+
72+
According to the problem description,
73+
74+
If an integer $x$ is a prime number, then its largest proper divisor is $1$, so $x / 1 = x$, meaning $x$ cannot be divided further.
75+
76+
If an integer $x$ is not a prime number, we assume the largest proper divisor of $x$ is $y$, then $x / y$ must be a prime number. Therefore, we find the smallest prime factor $\textit{lpf}[x]$ such that $x \bmod \textit{lpf}[x] = 0$, making $x$ become $\textit{lpf}[x]$, at which point it cannot be divided further.
77+
78+
Thus, we can preprocess the smallest prime factor for each integer from $1$ to $10^6$. Then, we traverse the array from right to left. If the current element is greater than the next element, we change the current element to its smallest prime factor. If after changing the current element to its smallest prime factor it is still greater than the next element, it means the array cannot be made non-decreasing, and we return $-1$. Otherwise, we increment the operation count by one. Continue traversing until the entire array is processed.
79+
80+
The time complexity for preprocessing is $O(M \times \log \log M)$, where $M = 10^6$. The time complexity for traversing the array is $O(n)$, where $n$ is the length of the array. The space complexity is $O(M)$.
7181

7282
<!-- tabs:start -->
7383

7484
#### Python3
7585

7686
```python
77-
87+
mx = 10**6 + 1
88+
lpf = [0] * (mx + 1)
89+
for i in range(2, mx + 1):
90+
if lpf[i] == 0:
91+
for j in range(i, mx + 1, i):
92+
if lpf[j] == 0:
93+
lpf[j] = i
94+
95+
96+
class Solution:
97+
def minOperations(self, nums: List[int]) -> int:
98+
ans = 0
99+
for i in range(len(nums) - 2, -1, -1):
100+
if nums[i] > nums[i + 1]:
101+
nums[i] = lpf[nums[i]]
102+
if nums[i] > nums[i + 1]:
103+
return -1
104+
ans += 1
105+
return ans
78106
```
79107

80108
#### Java
81109

82110
```java
83-
111+
class Solution {
112+
private static final int MX = (int) 1e6 + 1;
113+
private static final int[] LPF = new int[MX + 1];
114+
static {
115+
for (int i = 2; i <= MX; ++i) {
116+
for (int j = i; j <= MX; j += i) {
117+
if (LPF[j] == 0) {
118+
LPF[j] = i;
119+
}
120+
}
121+
}
122+
}
123+
public int minOperations(int[] nums) {
124+
int ans = 0;
125+
for (int i = nums.length - 2; i >= 0; i--) {
126+
if (nums[i] > nums[i + 1]) {
127+
nums[i] = LPF[nums[i]];
128+
if (nums[i] > nums[i + 1]) {
129+
return -1;
130+
}
131+
ans++;
132+
}
133+
}
134+
return ans;
135+
}
136+
}
84137
```
85138

86139
#### C++
87140

88141
```cpp
89-
142+
const int MX = 1e6;
143+
int LPF[MX + 1];
144+
145+
auto init = [] {
146+
for (int i = 2; i <= MX; i++) {
147+
if (LPF[i] == 0) {
148+
for (int j = i; j <= MX; j += i) {
149+
if (LPF[j] == 0) {
150+
LPF[j] = i;
151+
}
152+
}
153+
}
154+
}
155+
return 0;
156+
}();
157+
158+
class Solution {
159+
public:
160+
int minOperations(vector<int>& nums) {
161+
int ans = 0;
162+
for (int i = nums.size() - 2; i >= 0; i--) {
163+
if (nums[i] > nums[i + 1]) {
164+
nums[i] = LPF[nums[i]];
165+
if (nums[i] > nums[i + 1]) {
166+
return -1;
167+
}
168+
ans++;
169+
}
170+
}
171+
return ans;
172+
}
173+
};
90174
```
91175
92176
#### Go
93177
94178
```go
179+
const mx int = 1e6
180+
181+
var lpf = [mx + 1]int{}
182+
183+
func init() {
184+
for i := 2; i <= mx; i++ {
185+
if lpf[i] == 0 {
186+
for j := i; j <= mx; j += i {
187+
if lpf[j] == 0 {
188+
lpf[j] = i
189+
}
190+
}
191+
}
192+
}
193+
}
194+
195+
func minOperations(nums []int) (ans int) {
196+
for i := len(nums) - 2; i >= 0; i-- {
197+
if nums[i] > nums[i+1] {
198+
nums[i] = lpf[nums[i]]
199+
if nums[i] > nums[i+1] {
200+
return -1
201+
}
202+
ans++
203+
}
204+
}
205+
return
206+
}
207+
```
95208

209+
#### TypeScript
210+
211+
```ts
212+
const mx = 10 ** 6;
213+
const lpf = Array(mx + 1).fill(0);
214+
for (let i = 2; i <= mx; ++i) {
215+
for (let j = i; j <= mx; j += i) {
216+
if (lpf[j] === 0) {
217+
lpf[j] = i;
218+
}
219+
}
220+
}
221+
222+
function minOperations(nums: number[]): number {
223+
let ans = 0;
224+
for (let i = nums.length - 2; ~i; --i) {
225+
if (nums[i] > nums[i + 1]) {
226+
nums[i] = lpf[nums[i]];
227+
if (nums[i] > nums[i + 1]) {
228+
return -1;
229+
}
230+
++ans;
231+
}
232+
}
233+
return ans;
234+
}
96235
```
97236

98237
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const int MX = 1e6;
2+
int LPF[MX + 1];
3+
4+
auto init = [] {
5+
for (int i = 2; i <= MX; i++) {
6+
if (LPF[i] == 0) {
7+
for (int j = i; j <= MX; j += i) {
8+
if (LPF[j] == 0) {
9+
LPF[j] = i;
10+
}
11+
}
12+
}
13+
}
14+
return 0;
15+
}();
16+
17+
class Solution {
18+
public:
19+
int minOperations(vector<int>& nums) {
20+
int ans = 0;
21+
for (int i = nums.size() - 2; i >= 0; i--) {
22+
if (nums[i] > nums[i + 1]) {
23+
nums[i] = LPF[nums[i]];
24+
if (nums[i] > nums[i + 1]) {
25+
return -1;
26+
}
27+
ans++;
28+
}
29+
}
30+
return ans;
31+
}
32+
};

0 commit comments

Comments
 (0)