-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Solutions added for LC problems 68, 1361
- Loading branch information
Showing
4 changed files
with
260 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package org.sean.greedy; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
/*** | ||
* 68. Text Justification | ||
*/ | ||
public class TextJustification { | ||
public List<String> fullJustify(String[] words, int maxWidth) { | ||
int cnt = words.length; | ||
int left = 0; | ||
int right = 0; | ||
|
||
List<String> output = new ArrayList<>(); | ||
while (right < cnt) { | ||
int sz = words[left].length(); | ||
if (sz == maxWidth) { // already fit the whole line? | ||
output.add(words[left]); | ||
right = left = left + 1; | ||
continue; | ||
} | ||
|
||
right = left + 1; | ||
while (right < cnt) { | ||
sz += words[right].length(); | ||
if (sz + 1 <= maxWidth) {// one blank | ||
sz++; | ||
right++; | ||
} else { | ||
break; | ||
} | ||
} | ||
StringBuilder builder = genStringBuilder(words, maxWidth, right, left); | ||
output.add(builder.toString()); | ||
|
||
if (right < cnt) { | ||
left = right; | ||
} | ||
} | ||
|
||
refineLastStrIfNeeded(maxWidth, output); | ||
|
||
return output; | ||
} | ||
|
||
private static void refineLastStrIfNeeded(int maxWidth, List<String> output) { | ||
int outCnt = output.size(); | ||
String last = output.get(outCnt - 1); | ||
String[] splits = last.split("\\s+"); | ||
System.out.println(Arrays.toString(splits)); | ||
|
||
if (splits.length > 1) { | ||
StringBuilder builder = new StringBuilder(); | ||
int lineCharCnt = 0; | ||
for (int i = 0; i < splits.length; i++) { | ||
builder.append(splits[i]); | ||
lineCharCnt += splits[i].length(); | ||
|
||
if (i != splits.length - 1) { | ||
builder.append(div); | ||
lineCharCnt++; | ||
} | ||
} | ||
if (lineCharCnt < maxWidth) { | ||
int dlt = maxWidth - lineCharCnt; | ||
while (dlt > 0) { | ||
builder.append(div); | ||
dlt--; | ||
} | ||
} | ||
output.set(outCnt - 1, builder.toString()); | ||
} | ||
} | ||
|
||
private static final char div = ' '; | ||
|
||
private static StringBuilder genStringBuilder(String[] words, int maxWidth, int right, int left) { | ||
// add [left, right-1] | ||
StringBuilder builder = new StringBuilder(); | ||
int subWordCnt = right - left; | ||
int blankCnt = subWordCnt - 1; | ||
if (blankCnt == 0) { | ||
blankCnt = 1; | ||
} | ||
|
||
int charSum = 0; | ||
for (int i = left; i < right; i++) { | ||
charSum += words[i].length(); | ||
} | ||
int blanks = maxWidth - charSum; | ||
|
||
int perBlank = blanks / blankCnt; | ||
int dltBlank = blanks % blankCnt; | ||
|
||
for (int i = left; i < right; i++) { | ||
builder.append(words[i]); | ||
|
||
if (i != right - 1 || left == right - 1) { // not for the last one | ||
|
||
for (int j = 0; j < perBlank; j++) { | ||
builder.append(div); | ||
} | ||
if (dltBlank > 0) { | ||
builder.append(div); | ||
dltBlank--; | ||
} | ||
} | ||
} | ||
return builder; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package org.sean.tree; | ||
|
||
/*** | ||
* 1361. Validate Binary Tree Nodes | ||
*/ | ||
public class BinaryTreeValidator { | ||
private boolean[] visited; | ||
|
||
/** | ||
* The flag indicates whether we've finished the validation for the subtrees | ||
*/ | ||
private Boolean validated = null; | ||
|
||
private int cnt; | ||
|
||
// O(N) | ||
public boolean validateBinaryTreeNodes(int n, int[] leftChild, int[] rightChild) { | ||
visited = new boolean[n]; | ||
|
||
// locate the candidate node as the root by checking inDegree property | ||
int[] inDegrees = new int[n]; | ||
for (int k = 0; k < n; k++) { | ||
if (leftChild[k] != -1) { | ||
inDegrees[leftChild[k]] += 1; | ||
} | ||
if (rightChild[k] != -1) { | ||
inDegrees[rightChild[k]] += 1; | ||
} | ||
} | ||
int root = -1; | ||
for (int j = 0; j < n; j++) { | ||
if (inDegrees[j] == 0) { | ||
root = j; | ||
break; | ||
} | ||
} | ||
if (root == -1) | ||
return false; | ||
|
||
validateBinaryTreeNodesHelper(root, leftChild, rightChild); | ||
|
||
return (validated == null || validated) && cnt == n; | ||
} | ||
|
||
private boolean validateBinaryTreeNodesHelper(int curr, int[] leftChild, int[] rightChild) { | ||
if (validated != null) | ||
return validated; | ||
|
||
if (visited[curr]) { | ||
validated = false; | ||
return false; | ||
} | ||
|
||
visited[curr] = true; | ||
cnt++; | ||
if (leftChild[curr] == -1 && rightChild[curr] == -1) | ||
return true; | ||
|
||
boolean leftRes = leftChild[curr] == -1 || validateBinaryTreeNodesHelper(leftChild[curr], leftChild, rightChild); | ||
boolean rightRes = rightChild[curr] == -1 || validateBinaryTreeNodesHelper(rightChild[curr], leftChild, rightChild); | ||
|
||
boolean ret = leftRes && rightRes; | ||
if (!ret) { | ||
validated = false; | ||
} | ||
return ret; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package org.sean.greedy; | ||
|
||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
import static org.junit.Assert.*; | ||
|
||
public class TextJustificationTest { | ||
|
||
private TextJustification editor; | ||
|
||
@Before | ||
public void setUp() throws Exception { | ||
editor = new TextJustification(); | ||
} | ||
|
||
@Test | ||
public void fullJustify() { | ||
List<String> list = editor.fullJustify(new String[]{ | ||
"What", "must", "be", "acknowledgment", "shall", "be" | ||
}, 16); | ||
|
||
List<String> expected = Arrays.asList( | ||
"What must be", | ||
"acknowledgment ", | ||
"shall be "); | ||
|
||
assertEquals(expected, list); | ||
} | ||
|
||
@Test | ||
public void fullJustifyMoreStrings() { | ||
List<String> out = editor.fullJustify(new String[]{ | ||
"Science", "is", "what", "we", "understand", "well", "enough", "to", "explain", "to", "a", "computer.", | ||
"Art", "is", "everything", "else", "we", "do" | ||
}, 20); | ||
|
||
List<String> expected = Arrays.asList( | ||
"Science is what we", | ||
"understand well", | ||
"enough to explain to", | ||
"a computer. Art is", | ||
"everything else we", | ||
"do " | ||
); | ||
assertEquals(expected, out); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package org.sean.tree; | ||
|
||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import static org.junit.Assert.*; | ||
|
||
public class BinaryTreeValidatorTest { | ||
|
||
private BinaryTreeValidator validator; | ||
|
||
@Before | ||
public void setUp() throws Exception { | ||
validator = new BinaryTreeValidator(); | ||
} | ||
|
||
@Test | ||
public void validateBinaryTreeNodes() { | ||
TreeNode root = new TreeNode(2); | ||
root.left = new TreeNode(1); | ||
root.right = new TreeNode(0); | ||
root.right.left = new TreeNode(3); | ||
|
||
boolean result = validator.validateBinaryTreeNodes(4, new int[]{3, -1, 1, -1}, | ||
new int[]{-1, -1, 0, -1}); | ||
assertTrue(result); | ||
} | ||
} |