Skip to content

Commit ddddcc1

Browse files
committed
Update
1 parent b086b18 commit ddddcc1

27 files changed

+1158
-34
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package array;
2+
3+
import java.util.HashSet;
4+
import java.util.Set;
5+
6+
/**
7+
* Description: https://leetcode.com/problems/first-missing-positive
8+
* Difficulty: Hard
9+
*/
10+
public class FirstMissingPositive {
11+
12+
/**
13+
* Time complexity: O(n)
14+
* Space complexity: O(1)
15+
*/
16+
public int firstMissingPositiveOptimalApproach(int[] nums) {
17+
int n = nums.length;
18+
19+
// first missing positive is either in range [1, n] or equal to n + 1
20+
for (int i = 0; i < n; i++) {
21+
// "kill" all non-positive values
22+
if (nums[i] <= 0) nums[i] = n + 1;
23+
}
24+
25+
// use array as hashtable
26+
// if number exists in an array mark its index (0-indexed) with negative value
27+
// [3, 4, 5, 1]
28+
// 3 exists -> [3, 4, -5, 1]
29+
// 4 exists -> [3, 4, -5, -1]
30+
// 5 is greater than n -> not interested
31+
// 1 exists -> [-1, 4, -5, -1]
32+
for (int i = 0; i < n; i++) {
33+
int num = Math.abs(nums[i]);
34+
if (num > n) continue;
35+
36+
nums[num - 1] = -Math.abs(nums[num - 1]);
37+
}
38+
39+
// [-1, 4, -5, -1] -> first non-negative value is 4 with index 2 (1-indexed) -> 2
40+
for (int i = 0; i < n; i++) {
41+
if (nums[i] > 0) return i + 1;
42+
}
43+
44+
// if all values are negative -> original array is e.g. [1, 2, 3, 4] -> 5
45+
return n + 1;
46+
}
47+
48+
/**
49+
* Time complexity: O(n)
50+
* Space complexity: O(n)
51+
*/
52+
public int firstMissingPositiveNaiveApproach(int[] nums) {
53+
Set<Integer> seen = new HashSet<>();
54+
for (int num : nums) {
55+
if (num > 0) seen.add(num);
56+
}
57+
58+
for (int num = 1; num < Integer.MAX_VALUE; num++) {
59+
if (!seen.contains(num)) return num;
60+
}
61+
62+
return -1;
63+
}
64+
}

src/array/NextPermutation.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package array;
2+
3+
/**
4+
* Description: https://leetcode.com/problems/next-permutation
5+
* Difficulty: Medium
6+
* Time complexity: O(n)
7+
* Space complexity: O(1)
8+
*/
9+
public class NextPermutation {
10+
11+
public void nextPermutation(int[] nums) {
12+
int firstDecreasing = nums.length - 2;
13+
// 1 5 8 [4] 7 6 5 3 1
14+
while (firstDecreasing >= 0
15+
&& nums[firstDecreasing] >= nums[firstDecreasing + 1]) {
16+
firstDecreasing--;
17+
}
18+
19+
if (firstDecreasing >= 0) {
20+
// 1 5 8 [4] 7 6 [5] 3 1
21+
int firstGreater = nums.length - 1;
22+
while (nums[firstGreater] <= nums[firstDecreasing]) {
23+
firstGreater--;
24+
}
25+
26+
// 1 5 8 [4] 7 6 [5] 3 1 -> 1 5 8 [5] 7 6 [4] 3 1
27+
swap(nums, firstDecreasing, firstGreater);
28+
}
29+
30+
// 1 5 8 5 [7 6 4 3 1] -> 1 5 8 5 [1 3 4 6 7]
31+
reverseStartingFrom(nums, firstDecreasing + 1);
32+
}
33+
34+
private void reverseStartingFrom(int[] nums, int start) {
35+
int left = start;
36+
int right = nums.length - 1;
37+
while (left < right) {
38+
swap(nums, left, right);
39+
left++;
40+
right--;
41+
}
42+
}
43+
44+
private void swap(int[] nums, int i, int j) {
45+
int tmp = nums[i];
46+
nums[i] = nums[j];
47+
nums[j] = tmp;
48+
}
49+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package binary;
2+
3+
/**
4+
* Description: https://leetcode.com/problems/bitwise-and-of-numbers-range
5+
* Difficulty: Medium
6+
*/
7+
public class BitwiseAndOfNumbersRange {
8+
9+
/**
10+
* Time complexity: O(1)
11+
* Space complexity: O(1)
12+
*/
13+
public int rangeBitwiseAndViaCommonPrefix(int left, int right) {
14+
// Result of an AND operation on range is a common prefix with the rest of the bits as zeroes
15+
// 9 = [00001] 001
16+
// 10 = [00001] 010
17+
// 11 = [00001] 011
18+
// 12 = [00001] 100
19+
// ----------------
20+
// & [00001] 000
21+
22+
int shift = 0;
23+
while (left != right) {
24+
// shift to the right, until common prefix is found
25+
left = left >> 1;
26+
right = right >> 1;
27+
shift++;
28+
}
29+
30+
// shift to the left to place an appropriate amount of zero bits
31+
return left << shift;
32+
}
33+
34+
/**
35+
* Time complexity: O(n)
36+
* Space complexity: O(1)
37+
*/
38+
public int rangeBitwiseAndNaiveApproach(int left, int right) {
39+
int result = left;
40+
for (int i = left + 1; i <= right; i++) {
41+
result &= i;
42+
}
43+
44+
return result;
45+
}
46+
}

src/binary_search/KokoEatingBananas.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public int minEatingSpeed(int[] piles, int hours) {
1717
int midSpeed = minSpeed + (maxSpeed - minSpeed) / 2;
1818

1919
if (canEatAllBananas(piles, hours, midSpeed)) {
20-
min = Math.min(min, midSpeed);
20+
min = midSpeed;
2121
maxSpeed = midSpeed - 1;
2222
} else {
2323
minSpeed = midSpeed + 1;

src/binary_search/MaximumCandiesAllocatedToKChildren.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public int maximumCandies(int[] candies, long children) {
2020
int midAllocation = minAllocation + (maxAllocation - minAllocation) / 2;
2121

2222
if (canAllocateCandyToEveryChild(candies, children, midAllocation)) {
23-
max = Math.max(max, midAllocation);
23+
max = minAllocation;
2424
minAllocation = midAllocation + 1;
2525
} else {
2626
maxAllocation = midAllocation - 1;

src/binary_search/MedianOfTwoSortedArrays.java

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
/**
44
* Description: https://leetcode.com/problems/median-of-two-sorted-arrays
55
* Difficulty: Hard
6-
* Time complexity: O(log min(m, n))
7-
* Space complexity: O(1)
86
*/
97
public class MedianOfTwoSortedArrays {
108

11-
public double findMedianSortedArraysV1(int[] small, int[] large) {
9+
/**
10+
* Time complexity: O(log min(m, n))
11+
* Space complexity: O(1)
12+
*/
13+
public double findMedianSortedArraysViaBinarySearchV1(int[] small, int[] large) {
1214
if (small.length > large.length) {
13-
return findMedianSortedArraysV1(large, small);
15+
return findMedianSortedArraysViaBinarySearchV1(large, small);
1416
}
1517

1618
int total = small.length + large.length;
@@ -43,9 +45,13 @@ public double findMedianSortedArraysV1(int[] small, int[] large) {
4345
throw new RuntimeException();
4446
}
4547

46-
public double findMedianSortedArraysV2(int[] small, int[] large) {
48+
/**
49+
* Time complexity: O(log min(m, n))
50+
* Space complexity: O(1)
51+
*/
52+
public double findMedianSortedArraysViaBinarySearchV2(int[] small, int[] large) {
4753
if (small.length > large.length) {
48-
return findMedianSortedArraysV2(large, small);
54+
return findMedianSortedArraysViaBinarySearchV2(large, small);
4955
}
5056

5157
int total = small.length + large.length;
@@ -72,4 +78,41 @@ public double findMedianSortedArraysV2(int[] small, int[] large) {
7278

7379
throw new RuntimeException();
7480
}
81+
82+
/**
83+
* Time complexity: O(m + n)
84+
* Space complexity: O(m + n)
85+
*/
86+
public double findMedianSortedArraysViaMerge(int[] first, int[] second) {
87+
int[] merged = merge(first, second);
88+
int length = merged.length;
89+
return length % 2 == 0
90+
? (merged[length / 2 - 1] + merged[length / 2]) / 2.0
91+
: (double) merged[length / 2];
92+
}
93+
94+
private int[] merge(int[] first, int[] second) {
95+
int[] merged = new int[first.length + second.length];
96+
97+
int i = 0;
98+
int j = 0;
99+
int k = 0;
100+
while (i < first.length && j < second.length) {
101+
if (first[i] <= second[j]) {
102+
merged[k++] = first[i++];
103+
} else {
104+
merged[k++] = second[j++];
105+
}
106+
}
107+
108+
while (i < first.length) {
109+
merged[k++] = first[i++];
110+
}
111+
112+
while (j < second.length) {
113+
merged[k++] = second[j++];
114+
}
115+
116+
return merged;
117+
}
75118
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package binary_tree;
2+
3+
/**
4+
* Description: https://leetcode.com/problems/insufficient-nodes-in-root-to-leaf-paths
5+
* Difficulty: Medium
6+
* Time complexity: O(n)
7+
* Space complexity: O(h)
8+
*/
9+
public class InsufficientNodesInRootToLeafPaths {
10+
11+
public TreeNode sufficientSubset(TreeNode root, int limit) {
12+
return removeInsufficientNodes(root, 0, limit);
13+
}
14+
15+
private TreeNode removeInsufficientNodes(TreeNode root, int currentPathSum, int limit) {
16+
if (root == null) return null;
17+
18+
if (isLeaf(root)) {
19+
// remove insufficient leaf
20+
return currentPathSum + root.val >= limit ? root : null;
21+
}
22+
23+
root.left = removeInsufficientNodes(root.left, currentPathSum + root.val, limit);
24+
root.right = removeInsufficientNodes(root.right, currentPathSum + root.val, limit);
25+
26+
// if node became a leaf -> all the paths through it were insufficient -> remove it
27+
return isLeaf(root) ? null : root;
28+
}
29+
30+
private boolean isLeaf(TreeNode root) {
31+
return root.left == null && root.right == null;
32+
}
33+
34+
private static class TreeNode {
35+
int val;
36+
TreeNode left;
37+
TreeNode right;
38+
}
39+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package binary_tree;
2+
3+
import java.util.LinkedList;
4+
import java.util.Queue;
5+
6+
/**
7+
* Description: https://leetcode.com/problems/maximum-level-sum-of-a-binary-tree
8+
* Difficulty: Medium
9+
* Time complexity: O(n)
10+
* Space complexity: O(n)
11+
*/
12+
public class MaximumLevelSumOfBinaryTree {
13+
14+
public int maxLevelSum(TreeNode root) {
15+
Queue<TreeNode> planned = new LinkedList<>();
16+
planned.offer(root);
17+
18+
int maxSum = Integer.MIN_VALUE;
19+
int maxLevel = 0;
20+
int currentLevel = 0;
21+
while (!planned.isEmpty()) {
22+
int levelSize = planned.size();
23+
int levelSum = 0;
24+
currentLevel++;
25+
for (int i = 0; i < levelSize; i++) {
26+
TreeNode current = planned.poll();
27+
levelSum += current.val;
28+
29+
if (current.left != null) planned.offer(current.left);
30+
if (current.right != null) planned.offer(current.right);
31+
}
32+
33+
if (levelSum > maxSum) {
34+
maxSum = levelSum;
35+
maxLevel = currentLevel;
36+
}
37+
}
38+
39+
return maxLevel;
40+
}
41+
42+
private static class TreeNode {
43+
int val;
44+
TreeNode left;
45+
TreeNode right;
46+
}
47+
}

0 commit comments

Comments
 (0)