Skip to content

Commit 0a481f2

Browse files
author
FreeTymeKiyan
committed
update solutions
1 parent e387e6e commit 0a481f2

18 files changed

+1029
-1044
lines changed

src/main/java/com/freetymekiyan/algorithms/level/easy/MergeSortedArray.java

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,25 @@
1515
*/
1616
public class MergeSortedArray {
1717

18-
/**
19-
* Array. Two Pointers.
20-
* One pointer i at the end of nums1. Another pointer j at the end of nums2.
21-
* Compare their values and put the larger one at the end of nums1.
22-
* The index is m + n - 1.
23-
* If m - 1 == 0, nums1 is fully merged, merge the rest of nums2.
24-
*/
25-
public void merge(int[] nums1, int m, int[] nums2, int n) {
26-
for (int i = m - 1, j = n - 1, k = m + n - 1; k >= 0 && j >= 0; k--) {
27-
nums1[k] = (i < 0 || nums1[i] < nums2[j]) ? nums2[j--] : nums1[i--];
28-
}
18+
/**
19+
* Array. Two Pointers.
20+
* One pointer i at the end of nums1. Another pointer j at the end of nums2.
21+
* Compare their values and put the larger one at the end of nums1.
22+
* The index is m + n - 1.
23+
* If m - 1 == 0, nums1 is fully merged, merge the rest of nums2.
24+
*/
25+
public void merge(int[] nums1, int m, int[] nums2, int n) {
26+
for (int i = m - 1, j = n - 1, k = m + n - 1; k >= 0 && j >= 0; k--) {
27+
nums1[k] = (i < 0 || nums1[i] < nums2[j]) ? nums2[j--] : nums1[i--];
2928
}
29+
}
3030

31-
/**
32-
* Instead of 3 indices, use m-1 for nums1, n-1 for nums2.
33-
*/
34-
public void merge2(int[] nums1, int m, int[] nums2, int n) {
35-
for (int i = m + n - 1; i >= 0 && n - 1 >= 0; i--) {
36-
nums1[i] = (m - 1 < 0 || nums1[m - 1] < nums2[n - 1]) ? nums2[n-- - 1] : nums1[m-- - 1];
37-
}
31+
/**
32+
* Instead of 3 indices, use m-1 for nums1, n-1 for nums2.
33+
*/
34+
public void merge2(int[] nums1, int m, int[] nums2, int n) {
35+
for (int i = m + n - 1; i >= 0 && n - 1 >= 0; i--) {
36+
nums1[i] = (m - 1 < 0 || nums1[m - 1] < nums2[n - 1]) ? nums2[n-- - 1] : nums1[m-- - 1];
3837
}
38+
}
3939
}

src/main/java/com/freetymekiyan/algorithms/level/hard/EditDist.java

Lines changed: 0 additions & 79 deletions
This file was deleted.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.freetymekiyan.algorithms.level.hard;
2+
3+
/**
4+
* Given two words word1 and word2, find the minimum number of steps required
5+
* to convert word1 to word2. (each operation is counted as 1 step.)
6+
* <p>
7+
* You have the following 3 operations permitted on a word:
8+
* <p>
9+
* a) Insert a character
10+
* b) Delete a character
11+
* c) Replace a character
12+
* <p>
13+
* Tags: DP, String
14+
*/
15+
class EditDistance {
16+
17+
/**
18+
* DP, O(nm) Time, O(nm) Space
19+
* Searching for a path (sequence of edits) from the start string to the
20+
* final string
21+
* For two strings, X of length n, Y of length m
22+
* Define D(i,j): the edit distance between X[1..i] and Y[1..j]
23+
* The edit distance between X and Y is thus D(n,m)
24+
* <p>
25+
* Initialization: D(i,0) = i, D(0,j) = j
26+
* 1. D(i, j) = min(D(i - 1, j) + 1, D(i, j - 1) + 1, D(i - 1, j - 1) + 0
27+
* or 1), 0 is X(i) = Y(j), 1 if X(i) != Y(j)
28+
* D(N, M) is distance
29+
* <p>
30+
* Note that f[i][j] only depends on f[i-1][j-1], f[i-1][j] and f[i][j-1],
31+
* therefore we can reduce the space to O(n) by using only the (i-1)th
32+
* array and previous updated element(f[i][j-1]).
33+
*/
34+
public static int minDistance(String word1, String word2) {
35+
if (word1.equals(word2)) return 0;
36+
int m = word1.length();
37+
int n = word2.length();
38+
int[][] d = new int[m + 1][n + 1];
39+
d[0][0] = 0;
40+
for (int i = 1; i < m + 1; i++) d[i][0] = i;
41+
for (int j = 1; j < n + 1; j++) d[0][j] = j;
42+
43+
for (int i = 1; i < m + 1; i++) {
44+
for (int j = 1; j < n + 1; j++) {
45+
d[i][j] = Math.min(Math.min(d[i][j - 1] + 1, d[i - 1][j] + 1), word1.charAt(i - 1) == word2.charAt(j - 1) ? d[i - 1][j - 1] : d[i - 1][j - 1] + 1);
46+
}
47+
}
48+
49+
return d[m][n];
50+
}
51+
52+
/**
53+
* Optimal DP. Reduce table to a row.
54+
*/
55+
public static int minDistanceOptimal(String word1, String word2) {
56+
if (word1.equals(word2)) return 0;
57+
int m = word1.length();
58+
int n = word2.length();
59+
int[] d = new int[n + 1];
60+
d[0] = 0;
61+
for (int j = 1; j < n + 1; j++) d[j] = j;
62+
63+
for (int i = 1; i < m + 1; i++) {
64+
int prev = d[0];
65+
d[0] += 1;
66+
for (int j = 1; j < n + 1; j++) {
67+
int temp = d[j];
68+
d[j] = Math.min(Math.min(d[j - 1] + 1, d[j] + 1), word1.charAt(i - 1) == word2.charAt(j - 1) ? prev : prev + 1);
69+
prev = temp;
70+
}
71+
}
72+
73+
return d[n];
74+
}
75+
}

src/main/java/com/freetymekiyan/algorithms/level/hard/MaximalRectangle.java

Lines changed: 78 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -21,84 +21,84 @@
2121
*/
2222
public class MaximalRectangle {
2323

24-
/**
25-
* DP.
26-
* Three matrices: left, right, and height.
27-
* Height is number of continuous 1's that end at j.
28-
* Left is the left boundary of this height. The actual value is an index.
29-
* Right is the right boundary of this right. The actual value is index + 1.
30-
* The rectangle area of this height at row i and column j is: [right(i,j) - left(i,j)] * height(i,j).
31-
* <p>
32-
* Recurrence relations:
33-
* left(i,j) = max(left(i-1,j), leftBound)
34-
* leftBound is the leftmost 1 of this height at current row.
35-
* All left boundaries are initialized as 0, which is the leftmost possible.
36-
* <p>
37-
* right(i,j) = min(right(i-1,j), rightBound)
38-
* rightBound is the rightmost 1 of this height at current row + 1.
39-
* All right boundaries are initialized as n, which is the rightmost possible.
40-
* <p>
41-
* height(i,j) = height(i-1,j) + 1, if matrix[i][j]=='1'.
42-
* height(i,j) = 0, if matrix[i][j]=='0'.
43-
* <p>
44-
* Implementation:
45-
* Initialize left array and height as all zeroes, right array as the column length.
46-
* For each row in the matrix, update height, left, right arrays.
47-
* Then compute the area and record the maximum.
48-
* Stop when all grids are done.
49-
* https://discuss.leetcode.com/topic/6650/share-my-dp-solution
50-
* <p>
51-
* Note that the rectangle area we get is not the maximum at each grid, rather, it's the area of the rectangle of
52-
* the maximum possible height.
53-
* Why does that covers the maximum rectangle?
54-
* Because:
55-
* If the max rectangle has only 1 column, the bottom grid will have the max area.
56-
* If the max rectangle has > 1 columns, the bottom row will have the max area.
57-
*/
58-
public int maximalRectangle(char[][] matrix) {
59-
int m = matrix.length;
60-
int n = matrix[0].length;
61-
int[] left = new int[n];
62-
int[] right = new int[n];
63-
int[] height = new int[n];
64-
// Arrays.fill(left, 0);
65-
Arrays.fill(right, n);
66-
// Arrays.fill(height, 0);
67-
int max = 0;
68-
for (int i = 0; i < m; i++) {
69-
// Compute height (can do this from either side).
70-
for (int j = 0; j < n; j++) {
71-
if (matrix[i][j] == '1') {
72-
height[j]++;
73-
} else {
74-
height[j] = 0;
75-
}
76-
}
77-
// Compute left boundaries (must from left to right).
78-
int leftBound = 0; // Index of leftmost 1 of current row.
79-
for (int j = 0; j < n; j++) {
80-
if (matrix[i][j] == '1') {
81-
left[j] = Math.max(left[j], leftBound);
82-
} else {
83-
left[j] = 0;
84-
leftBound = j + 1;
85-
}
86-
}
87-
// Compute right boundaries (must from right to left).
88-
int rightBound = n; // Index + 1 of rightmost 1 of current row.
89-
for (int j = n - 1; j >= 0; j--) {
90-
if (matrix[i][j] == '1') {
91-
right[j] = Math.min(right[j], rightBound);
92-
} else {
93-
right[j] = n; // Like reset. Make sure right[j] >= curRight.
94-
rightBound = j;
95-
}
96-
}
97-
// Compute the area of rectangle (can do this from either side).
98-
for (int j = 0; j < n; j++) {
99-
max = Math.max(max, (right[j] - left[j]) * height[j]);
100-
}
24+
/**
25+
* DP.
26+
* Three matrices: left, right, and height.
27+
* Height is number of continuous 1's that end at j.
28+
* Left is the left boundary of this height. The actual value is an index.
29+
* Right is the right boundary of this right. The actual value is index + 1.
30+
* The rectangle area of this height at row i and column j is: [right(i,j) - left(i,j)] * height(i,j).
31+
* <p>
32+
* Recurrence relations:
33+
* left(i,j) = max(left(i-1,j), leftBound)
34+
* leftBound is the leftmost 1 of this height at current row.
35+
* All left boundaries are initialized as 0, which is the leftmost possible.
36+
* <p>
37+
* right(i,j) = min(right(i-1,j), rightBound)
38+
* rightBound is the rightmost 1 of this height at current row + 1.
39+
* All right boundaries are initialized as n, which is the rightmost possible.
40+
* <p>
41+
* height(i,j) = height(i-1,j) + 1, if matrix[i][j]=='1'.
42+
* height(i,j) = 0, if matrix[i][j]=='0'.
43+
* <p>
44+
* Implementation:
45+
* Initialize left array and height as all zeroes, right array as the column length.
46+
* For each row in the matrix, update height, left, right arrays.
47+
* Then compute the area and record the maximum.
48+
* Stop when all grids are done.
49+
* https://discuss.leetcode.com/topic/6650/share-my-dp-solution
50+
* <p>
51+
* Note that the rectangle area we get is not the maximum at each grid, rather, it's the area of the rectangle of
52+
* the maximum possible height.
53+
* Why does that covers the maximum rectangle?
54+
* Because:
55+
* If the max rectangle has only 1 column, the bottom grid will have the max area.
56+
* If the max rectangle has > 1 columns, the bottom row will have the max area.
57+
*/
58+
public int maximalRectangle(char[][] matrix) {
59+
int m = matrix.length;
60+
int n = matrix[0].length;
61+
int[] left = new int[n];
62+
int[] right = new int[n];
63+
int[] height = new int[n];
64+
// Arrays.fill(left, 0);
65+
Arrays.fill(right, n);
66+
// Arrays.fill(height, 0);
67+
int max = 0;
68+
for (int i = 0; i < m; i++) {
69+
// Compute height (can do this from either side).
70+
for (int j = 0; j < n; j++) {
71+
if (matrix[i][j] == '1') {
72+
height[j]++;
73+
} else {
74+
height[j] = 0;
10175
}
102-
return max;
76+
}
77+
// Compute left boundaries (must from left to right).
78+
int leftBound = 0; // Index of leftmost 1 of current row.
79+
for (int j = 0; j < n; j++) {
80+
if (matrix[i][j] == '1') {
81+
left[j] = Math.max(left[j], leftBound);
82+
} else {
83+
left[j] = 0;
84+
leftBound = j + 1;
85+
}
86+
}
87+
// Compute right boundaries (must from right to left).
88+
int rightBound = n; // Index + 1 of rightmost 1 of current row.
89+
for (int j = n - 1; j >= 0; j--) {
90+
if (matrix[i][j] == '1') {
91+
right[j] = Math.min(right[j], rightBound);
92+
} else {
93+
right[j] = n; // Like reset. Make sure right[j] >= curRight.
94+
rightBound = j;
95+
}
96+
}
97+
// Compute the area of rectangle (can do this from either side).
98+
for (int j = 0; j < n; j++) {
99+
max = Math.max(max, (right[j] - left[j]) * height[j]);
100+
}
103101
}
102+
return max;
103+
}
104104
}

0 commit comments

Comments
 (0)