Skip to content

Commit e3be23f

Browse files
committed
Add python solutions to all array problems
1 parent eacd497 commit e3be23f

8 files changed

+314
-50
lines changed

leetcode/238.product-of-array-except-self.md

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,37 @@
11
## [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self)
22

3-
The product except self comes from the prefix and suffix of `i`. And we can calculate the prefix / suffix from the first and last index:
3+
For the index `i`, we can calculate the product of all elements before `i` and all elements after `i`. That is the prefix and suffix product. So we can iterate to calculate the product of all elements to the left of each element and all elements to the right of each element.
44

55
```js
6-
|Prefix| X |Suffix|
6+
|Prefix| i |Suffix|
77
```
88

99
* `prefix[i] = prefix[i - 1] * nums[i - 1]`
1010
* `suffix[i] = suffix[i + 1] * nums[i + 1]`
1111

1212
```js
13-
2, 3, 5
13+
input [2, 3, 5]
1414
prefix[i] 1 2 6
1515
suefix[i] 15 5 1
1616
```
1717

1818
Then we multiple the prefix and suffix together.
1919

20+
```python
21+
def productExceptSelf(self, nums: List[int]) -> List[int]:
22+
n = len(nums)
23+
prefix_prod = [1] * n
24+
suffix_prod = [1] * n
25+
for i in range(1, n):
26+
prefix_prod[i] = prefix_prod[i - 1] * nums[i - 1]
27+
for i in range(n - 2, -1, -1):
28+
suffix_prod[i] = suffix_prod[i + 1] * nums[i + 1]
29+
30+
answer = [1] * n
31+
for i in range(0, n):
32+
answer[i] = prefix_prod[i] * suffix_prod[i]
33+
return answer
34+
```
2035

2136
```kotlin
2237
fun productExceptSelf(nums: IntArray): IntArray {
@@ -39,8 +54,24 @@ fun productExceptSelf(nums: IntArray): IntArray {
3954
}
4055
```
4156

57+
* **Time Complexity**: `O(n)`.
58+
* **Space Complexity**: `O(n)`.
59+
4260
### Space Optimization
43-
We can use `prefixProducts` as answer array (the answer array does not count as extra space), and keep track the suffix to get the answer.
61+
We can use answer array as prefix product (the answer array does not count as extra space), and keep track the suffix to get the answer.
62+
63+
```python
64+
def productExceptSelf(self, nums: List[int]) -> List[int]:
65+
n = len(nums)
66+
answers = [1] * n
67+
for i in range(1, n):
68+
answers[i] = answers[i - 1] * nums[i - 1]
69+
suffix = nums[n - 1]
70+
for i in range(n - 2, -1, -1):
71+
answers[i] *= suffix
72+
suffix *= nums[i]
73+
return answers
74+
```
4475

4576
```kotlin
4677
fun productExceptSelf(nums: IntArray): IntArray {
@@ -51,10 +82,12 @@ fun productExceptSelf(nums: IntArray): IntArray {
5182
}
5283
var suffix = nums[nums.size - 1]
5384
for (i in nums.size - 2 downTo 0) {
54-
answers[i] = answers[i] * suffix
85+
answers[i] *= suffix
5586
suffix *= nums[i]
5687
}
57-
5888
return answers
5989
}
60-
```
90+
```
91+
92+
* **Time Complexity**: `O(n)`.
93+
* **Space Complexity**: `O(1)`.
Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,49 @@
11
## [2874. Maximum Value of an Ordered Triplet II](https://leetcode.com/problems/maximum-value-of-an-ordered-triplet-ii/description/)
22

3-
To find the maximum value of `(nums[i] - nums[j]) * nums[k]` where `i < j < k`, we try to find the maximum of `nums[i]` from left and `nums[k]` from right. Then we iterate `nums[j]` from left to right to find the maximum value.
3+
To find the maximum value of `(nums[i] - nums[j]) * nums[k]` where `i < j < k`, we try to find the maximum of `nums[i]` from left and `nums[k]` from right. Then we iterate `nums[j]` as minimum to find the global maximum value.
4+
5+
> TODO: There is a better solution with O(1) space complexity.
6+
7+
```python
8+
def maximumTripletValue(self, nums: List[int]) -> int:
9+
# (A[i] - A[j]) * A[k]
10+
# max min max
11+
# ( max ) * max
12+
n = len(nums)
13+
left_max = [0] * n
14+
right_max = [0] * n
15+
left_max[0] = nums[0]
16+
for i in range(1, n):
17+
left_max[i] = max(left_max[i - 1], nums[i])
18+
right_max[-1] = nums[-1]
19+
for i in range(n - 2, -1, -1):
20+
right_max[i] = max(right_max[i + 1], nums[i])
21+
22+
answer = -inf
23+
for i in range(1, n - 1):
24+
answer = max(answer, (left_max[i - 1] - nums[i]) * right_max[i + 1])
25+
return answer if answer > 0 else 0
26+
```
427

528
```kotlin
629
fun maximumTripletValue(nums: IntArray): Long {
730
val n = nums.size
8-
// The max from left to right
9-
val maxLeft = IntArray(n)
10-
// The max from right to left
11-
val maxRight = IntArray(n)
12-
13-
maxLeft[0] = nums[0]
14-
maxRight[n - 1] = nums[n - 1]
15-
31+
val leftMax = IntArray(n) { Int.MIN_VALUE }
32+
val rightMax = IntArray(n) { Int.MIN_VALUE }
33+
leftMax[0] = nums[0]
1634
for (i in 1 until n) {
17-
maxLeft[i] = maxOf(maxLeft[i - 1], nums[i])
35+
leftMax[i] = maxOf(leftMax[i - 1], nums[i])
1836
}
37+
rightMax[n - 1] = nums[n - 1]
1938
for (i in n - 2 downTo 0) {
20-
maxRight[i] = maxOf(maxRight[i + 1], nums[i])
39+
rightMax[i] = maxOf(rightMax[i + 1], nums[i])
2140
}
22-
2341
var result = Long.MIN_VALUE
2442
for (i in 1 until n - 1) {
25-
result = maxOf(result, (maxLeft[i - 1] - nums[i]) * maxRight[i + 1].toLong())
43+
result = maxOf(result, (leftMax[i - 1] - nums[i]).toLong() * rightMax[i + 1])
2644
}
2745
return if (result < 0) 0 else result
2846
}
29-
```
47+
```
48+
* **Time Complexity**: O(n).
49+
* **Space Complexity**: O(n).
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
## [2909. Minimum Sum of Mountain Triplets II](https://leetcode.com/problems/minimum-sum-of-mountain-triplets-ii/description/)
2+
3+
### Prefix && Surfix
4+
We're going to find the minimum sum of mountain triplets. To minimize the sum, we can find the minimum of the first and the third number, then iterate the second number as peak to find the global minimum sum.
5+
6+
```python
7+
def minimumSum(self, nums: List[int]) -> int:
8+
n = len(nums)
9+
left_min = [0] * n
10+
right_min = [0] * n
11+
left_min[0] = nums[0]
12+
for i in range(1, n):
13+
left_min[i] = min(left_min[i - 1], nums[i])
14+
15+
right_min[-1] = nums[-1]
16+
for i in range(n - 2, -1, -1):
17+
right_min[i] = min(right_min[i + 1], nums[i])
18+
19+
answer = inf
20+
for i in range(1, n - 1):
21+
if left_min[i - 1] < nums[i] and right_min[i + 1] < nums[i]:
22+
answer = min(answer, left_min[i - 1] + nums[i] + right_min[i + 1])
23+
return answer if answer != inf else -1
24+
```
25+
26+
```kotlin
27+
fun minimumSum(nums: IntArray): Int {
28+
val n = nums.size
29+
// The min value when consider current value and left part
30+
val leftMin = IntArray(n) { Int.MAX_VALUE }
31+
val rightMin = IntArray(n)
32+
33+
for (i in 1 until n) {
34+
leftMin[i] = minOf(nums[i], leftMin[i - 1])
35+
}
36+
rightMin[n - 1] = nums[n - 1]
37+
for (i in n - 2 downTo 0) {
38+
rightMin[i] = minOf(nums[i], rightMin[i + 1])
39+
}
40+
var minSum = Int.MAX_VALUE
41+
for (i in 1 until n - 1) {
42+
// Remember this check if the triplets are valid mountain
43+
if (leftMin[i - 1] < nums[i] && rightMin[i + 1] < nums[i]) {
44+
minSum = minOf(minSum, leftMin[i - 1] + nums[i] + rightMin[i + 1])
45+
}
46+
}
47+
return if (minSum == Int.MAX_VALUE) -1 else minSum
48+
}
49+
```
50+
* **Time Complexity**: O(n).
51+
* **Space Complexity**: O(n).

leetcode/621.task-scheduler.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ fun leastInterval(tasks: CharArray, n: Int): Int {
4646
counts[task - 'A']++
4747
val count = counts[task - 'A']
4848
if (max < count) {
49-
max = count
49+
max = count`
5050
maxCount = 1
5151
} else if (max == count) {
5252
maxCount++

leetcode/845.longest-mountain-in-array.md

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,45 @@
11
## [845. Longest Mountain in Array](https://leetcode.com/problems/longest-mountain-in-array)
22

33
### Two Pointers
4-
We locale the starting index of mountain, if found then start to climb the mountain. (mind the case it only goes up no down).
4+
We iterate the starting point to climb, then try to finish the mountain. If we can find the peak and the down side, then we can calculate the length of the mountain.
5+
6+
```python
7+
def longestMountain(self, arr: List[int]) -> int:
8+
n = len(arr)
9+
start = 0
10+
end = 0
11+
max_length = 0
12+
while start < n:
13+
if start + 1 < n and arr[start] < arr[start + 1]:
14+
end = start
15+
while end + 1 < n and arr[end] < arr[end + 1]:
16+
end += 1
17+
if end + 1 < n and arr[end] > arr[end + 1]:
18+
while end + 1 < n and arr[end] > arr[end + 1]:
19+
end += 1
20+
max_length = max(max_length, end - start + 1)
21+
start = end
22+
else:
23+
start += 1
24+
return max_length
25+
```
526

627
```kotlin
728
fun longestMountain(arr: IntArray): Int {
829
var start = 0
930
var end = 0
1031
var maxLength = 0
1132
while (start < arr.size) {
12-
// If we can start to climb
33+
// We find the starting point to climb
1334
if (start + 1 < arr.size && arr[start] < arr[start + 1]) {
1435
end = start
15-
// Go up to find the peak
36+
// Keep going up to find the peak
1637
while (end + 1 < arr.size && arr[end] < arr[end + 1]) {
1738
end++
1839
}
19-
// We have make sure there is down side.
40+
// Then start to go down
2041
if (end + 1 < arr.size && arr[end] > arr[end + 1]) {
21-
// Go down
42+
// Keep going down
2243
while (end + 1 < arr.size && arr[end] > arr[end + 1]) {
2344
end++
2445
}
@@ -32,12 +53,51 @@ fun longestMountain(arr: IntArray): Int {
3253
}
3354
return maxLength
3455
}
56+
57+
// Or same idea with the same implementation of [941. Valid Mountain Array](941.valid-mountain-array.md)
58+
fun longestMountain(arr: IntArray): Int {
59+
var longest = 0
60+
if (arr.size < 3) return 0
61+
var start = 0
62+
var end = 0
63+
while (start + 1 < arr.size) {
64+
// Find the starting point to climb
65+
if (arr[start] < arr[start + 1]) {
66+
end = start + 1
67+
var goUp = false
68+
var goDown = false
69+
// Try to finish the mountain
70+
while (end < arr.size) {
71+
if (arr[end - 1] < arr[end]) {
72+
if (goDown) break
73+
goUp = true
74+
} else if (arr[end - 1] > arr[end]) {
75+
if (!goUp) break
76+
goDown = true
77+
} else {
78+
break
79+
}
80+
end++
81+
}
82+
// If we find the valid mountain
83+
if (goUp && goDown) {
84+
longest = maxOf(longest, end - start)
85+
}
86+
// End - 1 because `end` is the first element that breaks the mountain, so we need to go back one step.
87+
start = end - 1
88+
} else {
89+
start++
90+
}
91+
}
92+
return longest
93+
}
3594
```
3695
* **Time Complexity**: `O(n)`.
3796
* **Space Complexity**: `O(1)`.
3897

3998

4099
### Simulation (AC)
100+
> Feel free to skip the following solution since it's more complex than the above one.
41101
```kotlin
42102
//
43103
// up, up: skip

0 commit comments

Comments
 (0)