Skip to content

Commit 29f22c8

Browse files
committed
Improved tasks 3510, 3515
1 parent a57cce3 commit 29f22c8

File tree

3 files changed

+186
-161
lines changed

3 files changed

+186
-161
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2105,11 +2105,11 @@
21052105
| 3518 |[Smallest Palindromic Rearrangement II](src/main/java/g3501_3600/s3518_smallest_palindromic_rearrangement_ii)| Hard | String, Hash_Table, Math, Counting, Combinatorics | 34 | 100.00
21062106
| 3517 |[Smallest Palindromic Rearrangement I](src/main/java/g3501_3600/s3517_smallest_palindromic_rearrangement_i)| Medium | String, Sorting, Counting_Sort | 33 | 100.00
21072107
| 3516 |[Find Closest Person](src/main/java/g3501_3600/s3516_find_closest_person)| Easy | Math | 0 | 100.00
2108-
| 3515 |[Shortest Path in a Weighted Tree](src/main/java/g3501_3600/s3515_shortest_path_in_a_weighted_tree)| Hard | Array, Depth_First_Search, Tree, Segment_Tree, Binary_Indexed_Tree | 38 | 100.00
2108+
| 3515 |[Shortest Path in a Weighted Tree](src/main/java/g3501_3600/s3515_shortest_path_in_a_weighted_tree)| Hard | Array, Depth_First_Search, Tree, Segment_Tree, Binary_Indexed_Tree | 28 | 99.55
21092109
| 3514 |[Number of Unique XOR Triplets II](src/main/java/g3501_3600/s3514_number_of_unique_xor_triplets_ii)| Medium | Array, Math, Bit_Manipulation, Enumeration | 1349 | 100.00
21102110
| 3513 |[Number of Unique XOR Triplets I](src/main/java/g3501_3600/s3513_number_of_unique_xor_triplets_i)| Medium | Array, Math, Bit_Manipulation | 1 | 100.00
21112111
| 3512 |[Minimum Operations to Make Array Sum Divisible by K](src/main/java/g3501_3600/s3512_minimum_operations_to_make_array_sum_divisible_by_k)| Easy | Array, Math | 1 | 100.00
2112-
| 3510 |[Minimum Pair Removal to Sort Array II](src/main/java/g3501_3600/s3510_minimum_pair_removal_to_sort_array_ii)| Hard | Array, Hash_Table, Heap_Priority_Queue, Simulation, Linked_List, Ordered_Set, Doubly_Linked_List | 289 | 99.58
2112+
| 3510 |[Minimum Pair Removal to Sort Array II](src/main/java/g3501_3600/s3510_minimum_pair_removal_to_sort_array_ii)| Hard | Array, Hash_Table, Heap_Priority_Queue, Simulation, Linked_List, Ordered_Set, Doubly_Linked_List | 278 | 98.94
21132113
| 3509 |[Maximum Product of Subsequences With an Alternating Sum Equal to K](src/main/java/g3501_3600/s3509_maximum_product_of_subsequences_with_an_alternating_sum_equal_to_k)| Hard | Array, Hash_Table, Dynamic_Programming | 141 | 89.52
21142114
| 3508 |[Implement Router](src/main/java/g3501_3600/s3508_implement_router)| Medium | Array, Hash_Table, Binary_Search, Design, Ordered_Set, Queue | 137 | 100.00
21152115
| 3507 |[Minimum Pair Removal to Sort Array I](src/main/java/g3501_3600/s3507_minimum_pair_removal_to_sort_array_i)| Easy | Array, Hash_Table, Heap_Priority_Queue, Simulation, Linked_List, Ordered_Set, Doubly_Linked_List | 1 | 100.00

src/main/java/g3501_3600/s3510_minimum_pair_removal_to_sort_array_ii/readme.md

Lines changed: 90 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -45,103 +45,111 @@ The array `nums` is already sorted.
4545
## Solution
4646

4747
```java
48+
import java.util.Arrays;
49+
4850
public class Solution {
49-
private static class Segment {
50-
private final int start;
51-
private final int end;
52-
private Segment left;
53-
private Segment right;
54-
private int lIdx;
55-
private long lNum;
56-
private int rIdx;
57-
private long rNum;
58-
private boolean ok;
59-
private long minSum;
60-
private int li;
61-
private int ri;
62-
63-
public static Segment init(int[] arr) {
64-
return new Segment(arr, 0, arr.length - 1);
51+
public int minimumPairRemoval(int[] nums) {
52+
if (nums.length == 1) {
53+
return 0;
6554
}
66-
67-
public Segment(int[] arr, int s, int e) {
68-
start = s;
69-
end = e;
70-
if (s >= e) {
71-
lIdx = rIdx = s;
72-
lNum = rNum = arr[s];
73-
minSum = Long.MAX_VALUE;
74-
ok = true;
75-
return;
55+
int size = (int) Math.pow(2, Math.ceil(Math.log(nums.length - 1.0) / Math.log(2)));
56+
long[] segment = new long[size * 2 - 1];
57+
Arrays.fill(segment, Long.MAX_VALUE);
58+
int[] lefts = new int[size * 2 - 1];
59+
int[] rights = new int[size * 2 - 1];
60+
long[] sums = new long[nums.length];
61+
Arrays.fill(sums, Long.MAX_VALUE / 2);
62+
int[][] arrIdxToSegIdx = new int[nums.length][];
63+
sums[0] = nums[0];
64+
int count = 0;
65+
arrIdxToSegIdx[0] = new int[] {-1, size - 1};
66+
for (int i = 1; i < nums.length; i++) {
67+
if (nums[i] < nums[i - 1]) {
68+
count++;
7669
}
77-
int mid = s + ((e - s) >> 1);
78-
left = new Segment(arr, s, mid);
79-
right = new Segment(arr, mid + 1, e);
80-
merge();
70+
lefts[size + i - 2] = i - 1;
71+
rights[size + i - 2] = i;
72+
segment[size + i - 2] = nums[i - 1] + (long) nums[i];
73+
arrIdxToSegIdx[i] = new int[] {size + i - 2, size + i - 1};
74+
sums[i] = nums[i];
8175
}
82-
83-
private void merge() {
84-
lIdx = left.lIdx;
85-
lNum = left.lNum;
86-
rIdx = right.rIdx;
87-
rNum = right.rNum;
88-
ok = left.ok && right.ok && left.rNum <= right.lNum;
89-
minSum = left.minSum;
90-
li = left.li;
91-
ri = left.ri;
92-
if (left.rNum + right.lNum < minSum) {
93-
minSum = left.rNum + right.lNum;
94-
li = left.rIdx;
95-
ri = right.lIdx;
96-
}
97-
if (right.minSum < minSum) {
98-
minSum = right.minSum;
99-
li = right.li;
100-
ri = right.ri;
101-
}
76+
arrIdxToSegIdx[nums.length - 1][1] = -1;
77+
for (int i = size - 2; i >= 0; i--) {
78+
int l = 2 * i + 1;
79+
int r = 2 * i + 2;
80+
segment[i] = Math.min(segment[l], segment[r]);
10281
}
82+
return getRes(count, segment, lefts, rights, sums, arrIdxToSegIdx);
83+
}
10384

104-
public void update(int i, long n) {
105-
if (start <= i && end >= i) {
106-
if (start >= end) {
107-
lNum = rNum = n;
85+
private int getRes(
86+
int count,
87+
long[] segment,
88+
int[] lefts,
89+
int[] rights,
90+
long[] sums,
91+
int[][] arrIdxToSegIdx) {
92+
int res = 0;
93+
while (count > 0) {
94+
int segIdx = 0;
95+
while (2 * segIdx + 1 < segment.length) {
96+
int l = 2 * segIdx + 1;
97+
int r = 2 * segIdx + 2;
98+
if (segment[l] <= segment[r]) {
99+
segIdx = l;
108100
} else {
109-
left.update(i, n);
110-
right.update(i, n);
111-
merge();
101+
segIdx = r;
112102
}
113103
}
114-
}
115-
116-
public Segment remove(int i) {
117-
if (start > i || end < i) {
118-
return this;
119-
} else if (start >= end) {
120-
return null;
104+
int arrIdxL = lefts[segIdx];
105+
int arrIdxR = rights[segIdx];
106+
long numL = sums[arrIdxL];
107+
long numR = sums[arrIdxR];
108+
if (numL > numR) {
109+
count--;
121110
}
122-
left = left.remove(i);
123-
right = right.remove(i);
124-
if (null == left) {
125-
return right;
126-
} else if (null == right) {
127-
return left;
111+
long newSum = sums[arrIdxL] = sums[arrIdxL] + sums[arrIdxR];
112+
int[] leftPointer = arrIdxToSegIdx[arrIdxL];
113+
int[] rightPointer = arrIdxToSegIdx[arrIdxR];
114+
int prvSegIdx = leftPointer[0];
115+
int nextSegIdx = rightPointer[1];
116+
leftPointer[1] = nextSegIdx;
117+
if (prvSegIdx != -1) {
118+
int l = lefts[prvSegIdx];
119+
if (sums[l] > numL && sums[l] <= newSum) {
120+
count--;
121+
} else if (sums[l] <= numL && sums[l] > newSum) {
122+
count++;
123+
}
124+
modify(segment, prvSegIdx, sums[l] + newSum);
125+
}
126+
if (nextSegIdx != -1) {
127+
int r = rights[nextSegIdx];
128+
if (numR > sums[r] && newSum <= sums[r]) {
129+
count--;
130+
} else if (numR <= sums[r] && newSum > sums[r]) {
131+
count++;
132+
}
133+
modify(segment, nextSegIdx, newSum + sums[r]);
134+
lefts[nextSegIdx] = arrIdxL;
128135
}
129-
merge();
130-
return this;
136+
modify(segment, segIdx, Long.MAX_VALUE);
137+
res++;
131138
}
139+
return res;
132140
}
133141

134-
public int minimumPairRemoval(int[] nums) {
135-
Segment root = Segment.init(nums);
136-
int res = 0;
137-
while (!root.ok) {
138-
int l = root.li;
139-
int r = root.ri;
140-
root.update(l, root.minSum);
141-
root = root.remove(r);
142-
res++;
142+
private void modify(long[] segment, int idx, long num) {
143+
if (segment[idx] == num) {
144+
return;
145+
}
146+
segment[idx] = num;
147+
while (idx != 0) {
148+
idx = (idx - 1) / 2;
149+
int l = 2 * idx + 1;
150+
int r = 2 * idx + 2;
151+
segment[idx] = Math.min(segment[l], segment[r]);
143152
}
144-
return res;
145153
}
146154
}
147155
```

0 commit comments

Comments
 (0)