Skip to content

Commit

Permalink
✨ feat: Add #873 #974 #978 #1007 #1011
Browse files Browse the repository at this point in the history
  • Loading branch information
Maecenas committed Jun 19, 2019
1 parent 1c76f6e commit 8386211
Show file tree
Hide file tree
Showing 7 changed files with 427 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package LeetCode;

/*
https://leetcode.com/problems/minimum-domino-rotations-for-equal-row/
Medium. Array, Greedy.
In a row of dominoes, A[i] and B[i] represent the top and bottom halves of the i-th domino.
(A domino is a tile with two numbers from 1 to 6 - one on each half of the tile.)
We may rotate the i-th domino, so that A[i] and B[i] swap values.
Return the minimum number of rotations so that all the values in A are the same,
or all the values in B are the same.
If it cannot be done, return -1.
Example 1:
Input: A = [2,1,2,4,2,2], B = [5,2,6,2,3,2]
Output: 2
Explanation:
The first figure represents the dominoes as given by A and B: before we do any rotations.
If we rotate the second and fourth dominoes, we can make every value in the top row equal
to 2, as indicated by the second figure.
Example 2:
Input: A = [3,5,1,2,3], B = [3,6,3,3,4]
Output: -1
Explanation:
In this case, it is not possible to rotate the dominoes to make one row of values equal.
Note:
1 <= A[i], B[i] <= 6
2 <= A.length == B.length <= 20000
*/

class _1007_MinimumDominoRotationsForEqualRow {

public static int minDominoRotations(int[] A, int[] B) {
if (A == null || A.length < 2 || B == null || B.length != A.length) return 0;

final int len = A.length;

for (int i = 0, a = 0, b = 0; i < len && (A[i] == A[0] || B[i] == A[0]); i++) {
if (A[i] != A[0]) a++;
if (B[i] != A[0]) b++;
if (i == len - 1) return Math.min(a, b);
}

for (int i = 0, a = 0, b = 0; i < len && (A[i] == B[0] || B[i] == B[0]); i++) {
if (A[i] != B[0]) a++;
if (B[i] != B[0]) b++;
if (i == len - 1) return Math.min(a, b);
}
return -1;
}
}
116 changes: 116 additions & 0 deletions src/main/java/LeetCode/_1011_CapacityToShipPackagesWithinDDays.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package LeetCode;

/*
https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/
Medium. Array, Binary Search.
A conveyor belt has packages that must be shipped from one port to another within D days.
The i-th package on the conveyor belt has a weight of weights[i].
Each day, we load the ship with packages on the conveyor belt
(in the order given by weights). We may not load more weight than
the maximum weight capacity of the ship.
Return the least weight capacity of the ship that will result in all
the packages on the conveyor belt being shipped within D days.
Example 1:
Input: weights = [1,2,3,4,5,6,7,8,9,10], D = 5
Output: 15
Explanation:
A ship capacity of 15 is the minimum to ship all the packages in 5 days like this:
1st day: 1, 2, 3, 4, 5
2nd day: 6, 7
3rd day: 8
4th day: 9
5th day: 10
Note that the cargo must be shipped in the order given, so using a ship of
capacity 14 and splitting the packages into parts like
(2, 3, 4, 5), (1, 6, 7), (8), (9), (10) is not allowed.
Example 2:
Input: weights = [3,2,2,4,1,4], D = 3
Output: 6
Explanation:
A ship capacity of 6 is the minimum to ship all the packages in 3 days like this:
1st day: 3, 2
2nd day: 2, 4
3rd day: 1, 4
Example 3:
Input: weights = [1,2,3,1,1], D = 4
Output: 3
Explanation:
1st day: 1
2nd day: 2
3rd day: 3
4th day: 1, 1
Note:
1 <= D <= weights.length <= 50000
1 <= weights[i] <= 500
*/

class _1011_CapacityToShipPackagesWithinDDays {

/**
* O(log(sum(nums) - max(nums))), O(1)
* Binary Search the capacity to ship within D days
*/
public static int shipWithinDays(int[] weights, int D) {
if (weights == null || weights.length == 0 || D <= 0 || D > weights.length) return 0;

int lo = 0, hi = 0;
// lo = max(weights), hi = sum(weights)
for (int w : weights) {
lo = Math.max(lo, w);
hi += w;
}

while (lo < hi) {
int mid = lo + ((hi - lo) >> 1);
// extract into methods is faster
if (shipWithinDays(weights, D, mid)) {
hi = mid;
} else {
lo = mid + 1;
}
}
return lo;
}

public static int shipWithinDays2(int[] weights, int D) {
if (weights == null || weights.length == 0 || D <= 0 || D > weights.length) return 0;

int lo = 1, hi = (weights.length * 500) / D;
while (lo < hi) {
int mid = lo + ((hi - lo) >> 1);
if (shipWithinDays(weights, D, mid)) {
hi = mid;
} else {
lo = mid + 1;
}
}
return hi;
}

private static boolean shipWithinDays(int[] weights, int D, int capacity) {
int sum = 0;
for (int w : weights) {
if (w > capacity) return false;
if (sum + w > capacity) {
D--;
if (D <= 0) return false;
sum = w;
} else {
sum += w;
}
}
return D > 0;
}
}
3 changes: 3 additions & 0 deletions src/main/java/LeetCode/_509_FibonacciNumber.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ Given N, calculate F(N).
0 ≤ N ≤ 30.
*/

/**
* @see _873_LengthOfLongestFibonacciSubsequence
*/
class _509_FibonacciNumber {

private static final double SQRT_5 = Math.sqrt(5);
Expand Down
1 change: 1 addition & 0 deletions src/main/java/LeetCode/_53_MaximumSubarray.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ If you have figured out the O(n) solution,
/**
* @see _152_MaximumProductSubarray
* @see _918_MaximumSumCircularSubarray
* @see _978_LongestTurbulentSubarray
*/
class _53_MaximumSubarray {

Expand Down
108 changes: 108 additions & 0 deletions src/main/java/LeetCode/_873_LengthOfLongestFibonacciSubsequence.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package LeetCode;

/*
https://leetcode.com/problems/length-of-longest-fibonacci-subsequence/
Medium. Array, Dynamic Programming.
A sequence X_1, X_2, ..., X_n is fibonacci-like if:
n >= 3
X_i + X_{i+1} = X_{i+2} for all i + 2 <= n
Given a strictly increasing array A of positive integers forming a sequence,
find the length of the longest fibonacci-like subsequence of A.
If one does not exist, return 0.
(Recall that a subsequence is derived from another sequence A by deleting
any number of elements (including none) from A, without changing the order
of the remaining elements.
For example, [3, 5, 8] is a subsequence of [3, 4, 5, 6, 7, 8].)
Example 1:
Input: [1,2,3,4,5,6,7,8]
Output: 5
Explanation:
The longest subsequence that is fibonacci-like: [1,2,3,5,8].
Example 2:
Input: [1,3,7,11,12,14,18]
Output: 3
Explanation:
The longest subsequence that is fibonacci-like:
[1,11,12], [3,11,14] or [7,11,18].
Note:
3 <= A.length <= 1000
1 <= A[0] < A[1] < ... < A[A.length - 1] <= 10^9
(The time limit has been reduced by 50% for submissions in Java, C, and C++.)
*/

import java.util.HashMap;
import java.util.Map;

/**
* @see _509_FibonacciNumber
*/
class _873_LengthOfLongestFibonacciSubsequence {

/**
* O(n^2), O(nlogM), where M is the largest element in A
*/
public static int lenLongestFibSubseq(int[] A) {
if (A == null || A.length < 3) return 0;

final int len = A.length;
final HashMap<Integer, Integer> index = new HashMap<>(), dp = new HashMap<>();
for (int i = 0; i < len; i++) {
index.put(A[i], i);
}

int res = 0;
for (int k = 0; k < len; k++)
for (int j = 0; j < k; j++) {
// checking triplet (i, j, k) that i < j < k
int i = index.getOrDefault(A[k] - A[j], -1);
if (i < 0 || i >= j) continue;
// encode tuple uniquely as (i, j) -> (i * N + j)
int curr = dp.getOrDefault(i * len + j, 2) + 1;
// update (j, k)
dp.put(j * len + k, curr);
res = Math.max(res, curr);
}

return res;
}

/**
* O(n^2), O(n^2)
*/
public static int lenLongestFibSubseq2(int[] A) {
if (A == null || A.length < 3) return 0;

final int len = A.length;
final int[][] dp = new int[len][len];

int res = 0;
for (int k = 2; k < len; k++) {
int i = 0, j = k - 1;
while (i < j) {
int sum = A[i] + A[j];
if (sum < A[k]) {
i++;
} else if (sum > A[k]) {
j--;
} else {
dp[j][k] = dp[i][j] + 1;
res = Math.max(res, dp[j][k]);
j--;
i++;
}
}
}

return res == 0 ? 0 : res + 2;
}
}
49 changes: 49 additions & 0 deletions src/main/java/LeetCode/_974_SubarraySumsDivisibleByK.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package LeetCode;

/*
https://leetcode.com/problems/subarray-sums-divisible-by-k/
Medium. Array, Hash Table.
Given an array A of integers, return the number of (contiguous, non-empty)
subarrays that have a sum divisible by K.
Example 1:
Input: A = [4,5,0,-2,-3,1], K = 5
Output: 7
Explanation: There are 7 subarrays with a sum divisible by K = 5:
[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]
Note:
1 <= A.length <= 30000
-10000 <= A[i] <= 10000
2 <= K <= 10000
*/

/**
* @see _560_SubarraySumEqualsK
*/
class _974_SubarraySumsDivisibleByK {

public static int subarraysDivByK(int[] A, int K) {
if (A == null || A.length == 0 || K < 2) return 0;

final int[] count = new int[K];
// keep the same calculation for x % K = 0
// C_n^1 + C_n^2 = n + n * (n - 1) / 2
// = C_(n + 1)^2 = n * (n + 1) / 2
count[0] = 1;
int sum = 0;
for (int x : A) {
sum += x;
count[(sum % K + K) % K]++;
}

int res = 0;
for (int v : count) {
res += (v * (v - 1)) >> 1;
}
return res;
}
}
Loading

0 comments on commit 8386211

Please sign in to comment.