Skip to content

Commit 5083d1f

Browse files
committed
LeetCode: 307, 541, 268
1 parent 1e33273 commit 5083d1f

30 files changed

Lines changed: 918 additions & 317 deletions

src/main/java/org/gd/common/Commons.java

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ public static long fib(int n) throws ArithmeticException {
6565
* https://habr.com/ru/post/261159/
6666
*
6767
* @param n
68+
*
6869
* @return instance of {@link BigInteger}
6970
*/
7071
public static BigInteger bigFib(int n) {
@@ -84,10 +85,10 @@ public static BigInteger bigFib(int n) {
8485
}
8586

8687
public static BigInteger fib(BigInteger n) {
87-
if (n.compareTo(BigInteger.TWO) < 0)
88+
if (n.compareTo(BigInteger.TWO) < 0)
8889
return BigInteger.ONE;
8990

90-
if (n.compareTo(BIG_92) <= 0)
91+
if (n.compareTo(BIG_92) <= 0)
9192
return BigInteger.valueOf(fib(n.intValue()));
9293

9394
// TODO: implement it
@@ -151,7 +152,7 @@ public static double recursionPow(double v, int pow) { // TODO: implement this m
151152
case 3: return v * v * v;
152153
case 4: return v * v * v * v;
153154
}
154-
double half = recursionPow(v, pow / 2);
155+
double half = recursionPow(v, pow >> 1);
155156
return half * half * recursionPow(v, pow % 2);
156157
}
157158

@@ -169,6 +170,7 @@ public static long linearGausSum0(long count) {
169170
* 1 + 2 + 3 + 4 + ... + 97 + 98 + 99 + 100
170171
*
171172
* @param count
173+
*
172174
* @return
173175
*/
174176
public static long gausSum0(long count) {
@@ -189,8 +191,8 @@ public static long gausSum0(long count) {
189191
public static long euclideanAlgorithm(long a, long b) {
190192
if (a == b)
191193
return a;
192-
193-
while (a != 0 && b !=0) {
194+
195+
while (a != 0 && b != 0) {
194196
if (a > b) {
195197
a %= b;
196198
} else {
@@ -211,21 +213,21 @@ public static boolean trialDivision(long n) {
211213
return false;
212214
final double sqrt = Math.sqrt(n);
213215
for (long i = 3; i <= sqrt; i += 2) {
214-
if (n % i == 0)
216+
if (n % i == 0)
215217
return false;
216218
}
217219
return true;
218220
}
219221

220222
/**
221223
* Sieve of Eratosthenes
222-
*
224+
*
223225
* https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
224226
*/
225227
public static long[] sieveOfEratosthenes(long n) {
226-
if (n <= 2)
228+
if (n <= 2)
227229
return new long[]{};
228-
if (n == 3)
230+
if (n == 3)
229231
return new long[]{2};
230232

231233
final ArrayList<Long> list = new ArrayList<>();
@@ -236,7 +238,7 @@ public static long[] sieveOfEratosthenes(long n) {
236238
}
237239

238240
final long[] arr = new long[list.size()];
239-
for (int i = 0; i < list.size(); i++)
241+
for (int i = 0; i < list.size(); i++)
240242
arr[i] = list.get(i);
241243

242244
return arr;
@@ -249,14 +251,14 @@ public static long[] sieveOfEratosthenes(long n) {
249251
public static BigInteger linearGausSum(BigInteger count) {
250252
if (count == null)
251253
return BigInteger.ZERO;
252-
253-
if (count.compareTo(GAUS_MAX_VAL_BI) <= 0)
254+
255+
if (count.compareTo(GAUS_MAX_VAL_BI) <= 0)
254256
return BigInteger.valueOf(linearGausSum0(count.longValue()));
255257

256258
BigInteger sum = BigInteger.ZERO;
257259
for (BigInteger i = BigInteger.ONE; i.compareTo(count) <= 0; i = i.add(BigInteger.ONE))
258260
sum = sum.add(i);
259-
261+
260262
return sum;
261263
}
262264

@@ -276,6 +278,7 @@ public static BigInteger gausSum(BigInteger count) {
276278
return count.multiply(count.shiftRight(1).add(BigInteger.ONE));
277279
}
278280

281+
@SuppressWarnings("DuplicatedCode")
279282
public static long nextPowerOf2(long n) {
280283
n--;
281284
n |= n >> 1;
@@ -286,6 +289,7 @@ public static long nextPowerOf2(long n) {
286289
return n + 1;
287290
}
288291

292+
@SuppressWarnings("DuplicatedCode")
289293
public static long prevPowerOf2(long n) {
290294
n--;
291295
n |= n >> 1;
@@ -300,4 +304,15 @@ public static long prevPowerOf2(long n) {
300304
public static boolean isPowerOfTwo(long n) {
301305
return (n > 0) && ((n & (n - 1)) == 0);
302306
}
307+
308+
public static int digitsCount(int num) {
309+
return num == 0 ? 1 : (int) (Math.log10(Math.abs(num)) + 1);
310+
}
311+
312+
public static int maxDigitsCount(int[] arr) {
313+
int count = 0;
314+
for (int value : arr)
315+
count = Math.max(count, digitsCount(value));
316+
return count;
317+
}
303318
}
Lines changed: 93 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.gd.common;
22

3+
import java.util.LinkedList;
4+
35
/**
46
* https://www.geeksforgeeks.org/segment-tree-set-1-sum-of-given-range/
57
*
@@ -13,18 +15,13 @@ public class SegmentTree {
1315
private final int[] tree;
1416
private final int length;
1517

16-
SegmentTree(int[] arr) {
18+
public SegmentTree(int[] arr) {
1719
this(arr, 0, arr.length);
1820
}
1921

20-
public static void main(String[] args) {
21-
SegmentTree segmentTree = new SegmentTree(new int[]{0, 1, 2, 3});
22-
System.out.println(segmentTree);
23-
}
24-
2522
/**
2623
* Constructor to construct segment tree from given array. This constructor allocates memory for segment tree and
27-
* calls {@link #constructSTUtil(int, int, int)} to fill the allocated memory
24+
* calls {@link #construct(int, int, int)} to fill the allocated memory
2825
*
2926
* @see Commons#log(double, double)
3027
*/
@@ -35,15 +32,24 @@ private SegmentTree(int[] arr, int startIndex, int length) {
3532

3633
// Allocate memory for segment tree
3734
// Height of segment tree
38-
int x = (int) (Math.ceil(Math.log(length) / Math.log(2)));
35+
int treeHeight = (int) (Math.ceil(Math.log(length) / Math.log(2)));
3936

4037
// Maximum size of segment tree
41-
int maxSize = 2 * (int) Math.pow(2, x) - 1;
38+
39+
//int maxSize = 2 * (int) Math.pow(2, x) - 1;
40+
int arrayTreeSize = (2 << treeHeight) - 1;
4241

4342
// Memory allocation
44-
tree = new int[maxSize];
43+
tree = new int[arrayTreeSize];
4544

46-
constructSTUtil(startIndex, startIndex + length - 1, 0);
45+
construct(startIndex, startIndex + length - 1, 0);
46+
}
47+
48+
/**
49+
* A utility function to get the middle index from corner indexes.
50+
*/
51+
private static int getMid(int leftBound, int rightBound) {
52+
return leftBound + ((rightBound - leftBound) >> 1);
4753
}
4854

4955
/**
@@ -53,71 +59,50 @@ private SegmentTree(int[] arr, int startIndex, int length) {
5359
* @param rightBound right bound (inclusive)
5460
* @param treeIndex is index of current node in segment tree {@link #tree}
5561
*/
56-
private int constructSTUtil(int leftBound, int rightBound, int treeIndex) {
62+
private int construct(int leftBound, int rightBound, int treeIndex) {
5763

5864
// If there is one element in array, store it in current node of segment tree and return
5965
if (leftBound == rightBound)
6066
return tree[treeIndex] = arr[leftBound];
6167

6268
// If there are more than one elements, then recur for left and
6369
// right subtrees and store the sum of values in this node
64-
int mid = getMid(leftBound, rightBound);
65-
66-
int leftSum = constructSTUtil(leftBound, mid, ((treeIndex << 1) + 1));
67-
int rightSum = constructSTUtil((mid + 1), rightBound, ((treeIndex << 1) + 2));
70+
final int mid = getMid(leftBound, rightBound);
6871

69-
tree[treeIndex] = leftSum + rightSum;
72+
final int leftSum = construct(leftBound, mid, (treeIndex * 2 + 1));
73+
final int rightSum = construct((mid + 1), rightBound, (treeIndex * 2 + 2));
7074

71-
return tree[treeIndex];
75+
return tree[treeIndex] = leftSum + rightSum;
7276
}
7377

7478
/**
75-
* A utility function to get the middle index from corner indexes.
76-
*/
77-
private static int getMid(int leftBound, int rightBound) {
78-
return leftBound + ((rightBound - leftBound) >> 1);
79-
}
80-
81-
/*
82-
A recursive function to get the sum of values in given range
83-
of the array. The following are parameters for this function.
84-
85-
st --> Pointer to segment tree
86-
si --> Index of current node in the segment tree. Initially
87-
0 is passed as root is always at index 0
88-
leftBound & rightBound --> Starting and ending indexes of the segment represented
89-
by current node, i.e., st[si]
90-
qs & qe --> Starting and ending indexes of query range
91-
79+
* The function to update a value in input array and segment tree. It uses updateValueUtil() to update the value in
80+
* segment tree
9281
*/
82+
public void update(int index, int value) {
9383

94-
private int getSumUtil(int leftBound, int rightBound, int qs, int qe, int si) {
95-
// If segment of this node is a part of given range, then return
96-
// the sum of the segment
97-
if (qs <= leftBound && qe >= rightBound)
98-
return tree[si];
99-
100-
// If segment of this node is outside the given range
101-
if (rightBound < qs || leftBound > qe)
102-
return 0;
84+
if (index < 0 || index > length - 1)
85+
throw new IndexOutOfBoundsException();
10386

104-
// If a part of this segment overlaps with the given range
105-
int mid = getMid(leftBound, rightBound);
87+
// Get the difference between new value and old value
88+
int diff = value - arr[index];
10689

107-
int leftSum = getSumUtil(leftBound, mid, qs, qe, (2 * si + 1));
108-
int rightSum = getSumUtil((mid + 1), rightBound, qs, qe, (2 * si + 2));
90+
// Update the value in array
91+
arr[index] = value;
10992

110-
return leftSum + rightSum;
93+
// Update the values of nodes in segment tree
94+
updateValueUtil(0, length - 1, index, diff, 0);
11195
}
11296

113-
/*
114-
A recursive function to update the nodes which have the given
115-
index in their range. The following are parameters
116-
st, si, ss and se are same as getSumUtil()
117-
i --> index of the element to be updated. This index is in
118-
input array.
119-
diff --> Value to be added to all nodes which have i in range
120-
*/
97+
/**
98+
* A recursive function to update the nodes which have the given index in their range. The following are parameters
99+
*
100+
* @param leftBound Starting indexes of the segment represented by current node
101+
* @param rightBound ending indexes of the segment represented by current node, i.e., st[si]
102+
* @param index index of the element to be updated. This index is in input array
103+
* @param diff Value to be added to all nodes which have i in range
104+
* @param treeIndex Index of current node in the segment tree. Initially 0 is passed as root is always at index 0
105+
*/
121106
private void updateValueUtil(int leftBound, int rightBound, int index, int diff, int treeIndex) {
122107
// Base Case: If the input index lies outside the range of
123108
// this segment
@@ -135,34 +120,67 @@ private void updateValueUtil(int leftBound, int rightBound, int index, int diff,
135120
}
136121

137122
/**
138-
* The function to update a value in input array and segment tree. It uses updateValueUtil() to update the value in
139-
* segment tree
123+
* It mainly uses {@link #getSumUtil(int, int, int, int, int)}
124+
*
125+
* @return sum of elements in range from index qs (quey start) to qe (query end).
140126
*/
141-
void updateValue(int index, int value) {
127+
public int getSum(int leftBound, int rightBound) {
142128

143-
if (index < 0 || index > length - 1)
129+
if (leftBound < 0 || rightBound > length - 1 || leftBound > rightBound)
144130
throw new IndexOutOfBoundsException();
145131

146-
// Get the difference between new value and old value
147-
int diff = value - arr[index];
148-
149-
// Update the value in array
150-
arr[index] = value;
151-
152-
// Update the values of nodes in segment tree
153-
updateValueUtil(0, length - 1, index, diff, 0);
132+
return getSumUtil(0, length - 1, leftBound, rightBound, 0);
154133
}
155134

156135
/**
157-
* It mainly uses {@link #getSumUtil(int, int, int, int, int)}
136+
* A recursive function to get the sum of values in given range of the array. The following are parameters for this
137+
* function.
158138
*
159-
* @return sum of elements in range from index qs (quey start) to qe (query end).
139+
* @param treeIndex Index of current node in the segment tree. Initially 0 is passed as root is always at index
140+
* 0
141+
* @param treeLeftBound Starting indexes of the segment represented by current node
142+
* @param treeRightBound ending indexes of the segment represented by current node, i.e., st[si]
143+
* @param leftBound Starting indexes of query range
144+
* @param rightBound ending indexes of query range
160145
*/
161-
int getSum(int leftBound, int rightBound) {
146+
private int getSumUtil(int treeLeftBound, int treeRightBound, int leftBound, int rightBound, int treeIndex) {
162147

163-
if (leftBound < 0 || rightBound > length - 1 || leftBound > rightBound)
164-
throw new IndexOutOfBoundsException();
148+
// If segment of this node is a part of given range, then return
149+
// the sum of the segment
150+
if (leftBound <= treeLeftBound && rightBound >= treeRightBound)
151+
return tree[treeIndex];
165152

166-
return getSumUtil(0, length - 1, leftBound, rightBound, 0);
153+
// If segment of this node is outside the given range
154+
if (treeRightBound < leftBound || treeLeftBound > rightBound)
155+
return 0;
156+
157+
// If a part of this segment overlaps with the given range
158+
int mid = getMid(treeLeftBound, treeRightBound);
159+
160+
int leftSum = getSumUtil(treeLeftBound, mid, leftBound, rightBound, (treeIndex * 2 + 1));
161+
int rightSum = getSumUtil((mid + 1), treeRightBound, leftBound, rightBound, (treeIndex * 2 + 2));
162+
163+
return leftSum + rightSum;
164+
}
165+
166+
@Override
167+
public String toString() {
168+
169+
String format = "%" + Commons.maxDigitsCount(tree) + "d ";
170+
171+
LinkedList<int[]> q = new LinkedList<>();
172+
q.add(new int[]{0, 1});
173+
int[] bounds;
174+
StringBuilder sb = new StringBuilder();
175+
while ((bounds = q.poll()) != null) {
176+
for (int i = bounds[0]; i < Math.min(tree.length, bounds[1]); i++) {
177+
sb.append(String.format(format, tree[i]));
178+
}
179+
sb.append('\n');
180+
if (bounds[1] < tree.length) {
181+
q.add(new int[]{bounds[1], (bounds[1] << 1) + 1});
182+
}
183+
}
184+
return sb.toString();
167185
}
168186
}

src/main/java/org/gd/leetcode/p0057/Solution.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
@LeetCode(
1818
name = "Insert Interval",
1919
difficulty = LeetCode.Level.HARD,
20-
state = LeetCode.State.TODO,
20+
state = LeetCode.State.DONE,
2121
tags = {
2222
LeetCode.Tags.ARRAY,
2323
LeetCode.Tags.SORT

0 commit comments

Comments
 (0)