From 38809b2ccb84fea497fbe79cf1807e782a60bf61 Mon Sep 17 00:00:00 2001
From: Edward Tang <3278807+EdwardTang@users.noreply.github.com>
Date: Sun, 9 Feb 2020 17:28:10 -0800
Subject: [PATCH 1/6] Create gradle workflow
---
.github/workflows/gradle.yml | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
create mode 100644 .github/workflows/gradle.yml
diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
new file mode 100644
index 0000000000..f9412d07c3
--- /dev/null
+++ b/.github/workflows/gradle.yml
@@ -0,0 +1,19 @@
+name: Java CI
+
+on: [push]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK 1.8
+ uses: actions/setup-java@v1
+ with:
+ java-version: 1.8
+ - name: Grant execute permission for gradlew
+ run: chmod +x gradlew
+ - name: Build with Gradle
+ run: ./gradlew build
From 42e85821cc4d8ea7402efe001faf471577661a7d Mon Sep 17 00:00:00 2001
From: Edward Tang <3278807+EdwardTang@users.noreply.github.com>
Date: Sun, 9 Feb 2020 17:29:45 -0800
Subject: [PATCH 2/6] samsara box onsite (#1)
---
build.gradle | 1 +
.../java/com/company/samsara/box/Box.java | 129 ++++++++++++++++++
2 files changed, 130 insertions(+)
create mode 100644 src/main/java/com/company/samsara/box/Box.java
diff --git a/build.gradle b/build.gradle
index 7b91fb79f6..c1e940cf9f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -23,4 +23,5 @@ dependencies {
compile 'com.google.code.gson:gson:2.8.0'
compile 'junit:junit:4.12'
testCompile group: 'junit', name: 'junit', version:'4.12'
+ implementation 'org.apache.commons:commons-lang3:3.6'
}
diff --git a/src/main/java/com/company/samsara/box/Box.java b/src/main/java/com/company/samsara/box/Box.java
new file mode 100644
index 0000000000..3eced285cc
--- /dev/null
+++ b/src/main/java/com/company/samsara/box/Box.java
@@ -0,0 +1,129 @@
+package com.company.samsara.box;
+
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.PriorityQueue;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * PART 1: Implement a representation of valuable with two fields id and name.
+ *
+ *
PART 2: Implement a representation of box, which is used as a container of valuables.
+ * Implement two methods. First is to add a valuable to the box (given id as input). Second is to
+ * remove a valuable from the box(given valuable object as input)
+ *
+ *
PART3: Add an maximum size bar to the representation of box. Modify the add method so that if
+ * the total size of valuables in the box will exceed the box size bar, do not add and print an
+ * error message. Otherwise, add the valuable into the box.
+ *
+ *
PART 4: Implement a method to output the maximum valuable-size in the box whenever the method
+ * is called
+ */
+public class Box {
+
+ private int sizeBar;
+ private int currentSize;
+ private PriorityQueue maxValuables;
+ private Map contentMap;
+
+ public Box(int sizeBar) {
+ if(sizeBar <= 0) {
+ throw new IllegalArgumentException("Size bar of a box cannot be smaller thant or equal to zero");
+ }
+ this.sizeBar = sizeBar;
+ this.currentSize = 0;
+ maxValuables = new PriorityQueue<>((a,b)->(b.size - a.size));
+ contentMap = new HashMap<>();
+ }
+
+ public void addValuable(Valuable valuable) {
+ if(valuable == null) {
+ throw new IllegalArgumentException("added valuable cannot be null");
+ }
+
+ if(contentMap.containsKey(valuable.id)) {
+ throw new IllegalArgumentException("valuable is already in the box");
+ }
+
+ if(currentSize + valuable.size > sizeBar) {
+ throw new IllegalArgumentException(String.format("adding this valuable with size %d will exceeds the box' size bar %d", valuable.size, sizeBar));
+ }
+
+ contentMap.put(valuable.id, valuable);
+ maxValuables.offer(valuable);
+ currentSize += valuable.size;
+ System.out.println("Added " + valuable.toString() + ", current box size: " + currentSize + " maxValueSize: " + getMaxValuableSize());
+ }
+
+ public void removeValuable(int id) {
+ if(!contentMap.containsKey(id)) {
+ throw new IllegalArgumentException("valuable is no in the box");
+ }
+ Valuable removed = contentMap.remove(id);
+ maxValuables.remove(removed);
+ currentSize -= removed.size;
+ System.out.println("Removed " + removed.toString() + ", current box size: " + currentSize + " maxValueSize: " + getMaxValuableSize());
+ }
+
+ public int getMaxValuableSize() {
+ if(maxValuables.isEmpty()) {
+ return 0;
+ } else {
+ return maxValuables.peek().size;
+ }
+ }
+
+ public static void main(String[] args) {
+
+ Valuable v1 = new Valuable(1, "valuable 1", 1);
+ Valuable v10 = new Valuable(2, "valuable 10", 10);
+ Valuable v20 = new Valuable(3, "valuable 20", 20);
+ Valuable v29 = new Valuable(4, "valuable 29", 29);
+ Valuable v5 = new Valuable(5, "valuable 5", 5);
+ Valuable v9 = new Valuable(6, "valuable 9", 9);
+
+ Box aBox = new Box(30);
+ try{
+ aBox.addValuable(v1);
+ aBox.addValuable(v10);
+// aBox.addValuable(v20);
+ aBox.removeValuable(v10.id);
+ aBox.addValuable(v29);
+ aBox.removeValuable(v29.id);
+ aBox.addValuable(v5);
+ aBox.addValuable(v10);
+ aBox.addValuable(v9);
+ } catch (IllegalArgumentException e) {
+ System.out.println(e.getMessage());
+ }
+
+ }
+
+}
+
+class Valuable {
+ int id;
+ String name;
+ int size;
+
+ public Valuable(int id, String name, int size) {
+ if(StringUtils.isBlank(name)) {
+ throw new IllegalArgumentException("Valuabe cannot be blank");
+ }
+ if(size <= 0) {
+ throw new IllegalArgumentException("Valuabe size cannot be smaller than or equal to 0");
+ }
+ this.id = id;
+ this.name = name;
+ this.size = size;
+ }
+
+ @Override
+ public String toString() {
+ return "[id = " + id + ", name = " + name + ", size = " + size + "]";
+ }
+
+}
+
+
From 234d5656e5d0964d6fb0985db52a741dde6d71f7 Mon Sep 17 00:00:00 2001
From: Edward Tang <3278807+EdwardTang@users.noreply.github.com>
Date: Thu, 13 Feb 2020 17:33:53 -0800
Subject: [PATCH 3/6] snapchat vmware (#2)
* snapchat vmware
* fix formatting
---
.../java/com/company/samsara/box/Box.java | 70 +++-----
.../com/company/samsara/box/Valuable.java | 26 +++
.../tree/BinaryTreePostOrderIterator.java | 74 ++++++++
src/main/java/com/company/vmware/Robot.java | 170 ++++++++++++++++++
4 files changed, 299 insertions(+), 41 deletions(-)
create mode 100644 src/main/java/com/company/samsara/box/Valuable.java
create mode 100644 src/main/java/com/company/snapchat/phone/tree/BinaryTreePostOrderIterator.java
create mode 100644 src/main/java/com/company/vmware/Robot.java
diff --git a/src/main/java/com/company/samsara/box/Box.java b/src/main/java/com/company/samsara/box/Box.java
index 3eced285cc..88e0d837eb 100644
--- a/src/main/java/com/company/samsara/box/Box.java
+++ b/src/main/java/com/company/samsara/box/Box.java
@@ -1,6 +1,5 @@
package com.company.samsara.box;
-
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
@@ -28,46 +27,62 @@ public class Box {
private Map contentMap;
public Box(int sizeBar) {
- if(sizeBar <= 0) {
- throw new IllegalArgumentException("Size bar of a box cannot be smaller thant or equal to zero");
+ if (sizeBar <= 0) {
+ throw new IllegalArgumentException(
+ "Size bar of a box cannot be smaller thant or equal to zero");
}
this.sizeBar = sizeBar;
this.currentSize = 0;
- maxValuables = new PriorityQueue<>((a,b)->(b.size - a.size));
+ maxValuables = new PriorityQueue<>((a, b) -> (b.size - a.size));
contentMap = new HashMap<>();
}
public void addValuable(Valuable valuable) {
- if(valuable == null) {
+ if (valuable == null) {
throw new IllegalArgumentException("added valuable cannot be null");
}
- if(contentMap.containsKey(valuable.id)) {
+ if (contentMap.containsKey(valuable.id)) {
throw new IllegalArgumentException("valuable is already in the box");
}
- if(currentSize + valuable.size > sizeBar) {
- throw new IllegalArgumentException(String.format("adding this valuable with size %d will exceeds the box' size bar %d", valuable.size, sizeBar));
+ if (currentSize + valuable.size > sizeBar) {
+ throw new IllegalArgumentException(
+ String.format(
+ "adding this valuable with size %d will exceeds the box' size bar %d",
+ valuable.size, sizeBar));
}
contentMap.put(valuable.id, valuable);
maxValuables.offer(valuable);
currentSize += valuable.size;
- System.out.println("Added " + valuable.toString() + ", current box size: " + currentSize + " maxValueSize: " + getMaxValuableSize());
+ System.out.println(
+ "Added "
+ + valuable.toString()
+ + ", current box size: "
+ + currentSize
+ + " maxValueSize: "
+ + getMaxValuableSize());
}
public void removeValuable(int id) {
- if(!contentMap.containsKey(id)) {
+ if (!contentMap.containsKey(id)) {
throw new IllegalArgumentException("valuable is no in the box");
}
Valuable removed = contentMap.remove(id);
maxValuables.remove(removed);
currentSize -= removed.size;
- System.out.println("Removed " + removed.toString() + ", current box size: " + currentSize + " maxValueSize: " + getMaxValuableSize());
+ System.out.println(
+ "Removed "
+ + removed.toString()
+ + ", current box size: "
+ + currentSize
+ + " maxValueSize: "
+ + getMaxValuableSize());
}
public int getMaxValuableSize() {
- if(maxValuables.isEmpty()) {
+ if (maxValuables.isEmpty()) {
return 0;
} else {
return maxValuables.peek().size;
@@ -84,10 +99,10 @@ public static void main(String[] args) {
Valuable v9 = new Valuable(6, "valuable 9", 9);
Box aBox = new Box(30);
- try{
+ try {
aBox.addValuable(v1);
aBox.addValuable(v10);
-// aBox.addValuable(v20);
+ // aBox.addValuable(v20);
aBox.removeValuable(v10.id);
aBox.addValuable(v29);
aBox.removeValuable(v29.id);
@@ -97,33 +112,6 @@ public static void main(String[] args) {
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
-
}
-
}
-class Valuable {
- int id;
- String name;
- int size;
-
- public Valuable(int id, String name, int size) {
- if(StringUtils.isBlank(name)) {
- throw new IllegalArgumentException("Valuabe cannot be blank");
- }
- if(size <= 0) {
- throw new IllegalArgumentException("Valuabe size cannot be smaller than or equal to 0");
- }
- this.id = id;
- this.name = name;
- this.size = size;
- }
-
- @Override
- public String toString() {
- return "[id = " + id + ", name = " + name + ", size = " + size + "]";
- }
-
-}
-
-
diff --git a/src/main/java/com/company/samsara/box/Valuable.java b/src/main/java/com/company/samsara/box/Valuable.java
new file mode 100644
index 0000000000..7e33f0b9d5
--- /dev/null
+++ b/src/main/java/com/company/samsara/box/Valuable.java
@@ -0,0 +1,26 @@
+package com.company.samsara.box;
+
+import org.apache.commons.lang3.StringUtils;
+
+class Valuable {
+ int id;
+ String name;
+ int size;
+
+ public Valuable(int id, String name, int size) {
+ if (StringUtils.isBlank(name)) {
+ throw new IllegalArgumentException("Valuabe cannot be blank");
+ }
+ if (size <= 0) {
+ throw new IllegalArgumentException("Valuabe size cannot be smaller than or equal to 0");
+ }
+ this.id = id;
+ this.name = name;
+ this.size = size;
+ }
+
+ @Override
+ public String toString() {
+ return "[id = " + id + ", name = " + name + ", size = " + size + "]";
+ }
+}
diff --git a/src/main/java/com/company/snapchat/phone/tree/BinaryTreePostOrderIterator.java b/src/main/java/com/company/snapchat/phone/tree/BinaryTreePostOrderIterator.java
new file mode 100644
index 0000000000..4c0b717a41
--- /dev/null
+++ b/src/main/java/com/company/snapchat/phone/tree/BinaryTreePostOrderIterator.java
@@ -0,0 +1,74 @@
+package com.company.snapchat.phone.tree;
+
+import com.fishercoder.common.classes.TreeNode;
+import com.fishercoder.common.utils.TreeUtils;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.List;
+
+public class BinaryTreePostOrderIterator {
+
+ private Deque stack = new ArrayDeque<>();
+ private LinkedList out = new LinkedList<>();
+
+ // 1. Post-order is the reverse order of pre-order with traversing right substree before traversing
+ // left subtree:
+ // pre-order : root -> left-subtree -> right-subtree
+ // pre-order-visit-right-first: root -> right-subtree -> left-subtree
+ // reversed-(pre-order-visit-right-first): left-subtree -> right-subtree -> root
+ // post-order: left-subtree -> right-subtree -> root
+ //
+ // 2. And since stack is LIFO, we should push left substree to stack, then right substree.
+ // 3. So for next step, the top element of stack is right subtree.
+ // 4. And we need to also reverse the order of the elements poped from stack.
+ // 5. So we use another linkedList based stack to maintain the reverse order
+ public BinaryTreePostOrderIterator(TreeNode root) {
+ stack.addFirst(root);
+ while (!stack.isEmpty()) {
+ TreeNode node = stack.removeFirst();
+ out.addFirst(node);
+ if (node.left != null) {
+ stack.addFirst(node.left);
+ }
+ if (node.right != null) {
+ stack.addFirst(node.right);
+ }
+ }
+ }
+
+ public boolean hasNext() {
+ return !out.isEmpty();
+ }
+
+ public TreeNode next() {
+ if (!hasNext()) {
+ return null;
+ }
+ return out.removeFirst();
+ }
+
+ public static void main(String[] args) {
+
+ List list = Arrays.asList(new Integer[] {5, 3, 6, 2, 4, null, null, 1});
+ /**
+ * the tree for [5, 3, 6, 2, 4, null, null, 1], i.e. looks like the following:
+ 5
+ / \
+ 3 6
+ / \ / \
+ 2 4 # #
+ /
+ 1
+ */
+ TreeNode root = TreeUtils.constructBinaryTree(list);
+ List result = new ArrayList<>();
+ BinaryTreePostOrderIterator iterator = new BinaryTreePostOrderIterator(root);
+ while (iterator.hasNext()) {
+ result.add(iterator.next().val);
+ }
+ System.out.println(result.toString()); // [1, 2, 4, 3, 6, 5]
+ }
+}
diff --git a/src/main/java/com/company/vmware/Robot.java b/src/main/java/com/company/vmware/Robot.java
new file mode 100644
index 0000000000..9ed3ccc36d
--- /dev/null
+++ b/src/main/java/com/company/vmware/Robot.java
@@ -0,0 +1,170 @@
+package com.company.vmware;
+
+import java.util.LinkedList;
+
+/**
+ * Design Robot class that can move around on a two dimensional plane. It needs to be able to change
+ * its position, report its position and report its last move as described below. Implement a Robot
+ * class per following specifications: Fields: integer currentX - The robot's current x-coordinate
+ * in the 2D plane integer currentY - The robot's current y-coordinate in the 2D plane integer
+ * previousX - The robot's x-coordinate in the 2D plane prior to its most recent movement integer
+ * previousY - The robot's y-coordinate in the 2D plane prior to its most recent movement **Note: **
+ * The robot's initial location is at (x,y) coordinate (0,5)
+ *
+ * Parameterized Constructor: x - The value of currentX for the new Robot y - The value of
+ * currentY for the new Robot
+ *
+ *
public Robot(integer x, integer y) { } The robot created by this constructor is considered to
+ * have spawned at(0,5) and moved to (currentX, currentY) so (previousX, previousY) starts as (0,5)
+ *
+ *
Methods:
+ *
+ *
void printCurrentCoordinates() - Print two space-separated integers describing the robot's
+ * current x and y coordinates.
+ *
+ *
void moveX(integer dx) - Move the robot from current position(x,y) to new position(x+dx, y).
+ * Remember to maintain previousX.
+ *
+ *
void moveY(integer dy) - Move the robot from current position(x,y) to new position(x, y+dy).
+ * Remember to maintain previousY.
+ *
+ *
void printLastCoordinates() - Print two space-separated integers describing the robot's
+ * previousX and previousY coordinates. This will be called after the robot has moved from position
+ * (0,5) at least once
+ *
+ *
void printLastMove() - Print two space-separated values describing the robot's most recent
+ * movement
+ *
+ *
Sample input: 2 1, 1, 2, 0
+ *
+ *
Sample output: 0 5 , 2 1, x 1, 3 1, 3 1, x 2, 5 2, 5 2
+ *
+ *
Explanation: The firstRobot object is initially at position (0,5), so the call to
+ * firstRobot.printCurrentCoordinates() prints 0 5 For the secondRobot object created with the
+ * parameterized constructor, it was created and moved from (0,5) -> (2,1) so
+ * secondRobot.printCurrentCoordinates() prints 2 1. Next, we call the following sequence of methods
+ * on the secondRobot object.
+ *
+ *
secondRobot.moveX(1) moves the robot 1 unit from (2,1) -> (3,1)
+ *
+ *
secondRobot.printLastMove() prints x 1 as its last movement was moveX(1)
+ *
+ *
secondRobot.printCurrentCoordinates() prints 3 1 because it moved from (2,1) ->(3,1)
+ *
+ *
secondRobot.moveY(1) moves the robot 1 unit from (3,1) -> (3,2)
+ *
+ *
secondRobot.printLastCoordinates() prints 3 1 bcause its last movement was (3,1) -> (3,2), so
+ * the coordinates of its last location prior to the movement was (3,1) At this point, the test code
+ * adds 1 to dx => dx = 2 and subtracts 1 from dy => dy = 0
+ *
+ *
secondRobot.moveX(2) moves the robot from the (3,2) -> (5,2)
+ *
+ *
secondRobot.printLastMove() prints x 2 as its last movement was moveX(2)
+ *
+ *
secondRobot.printCurrentCoordinates() prints 5 2 because it moved from (3,2) -> (5,2)
+ *
+ *
secondRobot.moveY(0) moves the robot 0 units from (5,2) -> (5,2)
+ * secondRobot.printLastCoordinates() prints 5 2 because its last movment was (5,2) -> (5,2)
+ */
+
+/**
+ * High level: Use 4 stacks to keep track on robot's coordinate X and Y's position history and move
+ * history respectively. So the above example looks like the following with 4 stacks:
+ *
+ *
X [0 2 3 3 5 5
+ *
+ *
dX [0 2 1 0 2 0
+ *
+ *
Y [5 1 1 2 2 2
+ *
+ *
dY [0 -4 0 1 0 0
+ */
+public class Robot {
+ public static int INIT_X = 0;
+ public static int INIT_Y = 5;
+
+ private LinkedList xStack =
+ new LinkedList() {
+ {
+ add(INIT_X);
+ }
+ };
+ private LinkedList dxStack =
+ new LinkedList() {
+ {
+ add(0);
+ }
+ };
+ private LinkedList yStack =
+ new LinkedList() {
+ {
+ add(INIT_Y);
+ }
+ };
+ private LinkedList dyStack =
+ new LinkedList() {
+ {
+ add(0);
+ }
+ };
+
+ public Robot(int x, int y) {
+ dxStack.addLast(x - xStack.getLast());
+ xStack.addLast(x);
+ dyStack.addLast(y - yStack.getLast());
+ yStack.addLast(y);
+ System.out.println("initial curr (x, y): " + xStack.getLast() + " " + yStack.getLast());
+ System.out.println(
+ "initial last (x, y): "
+ + xStack.get(xStack.size() - 1 - 1)
+ + " "
+ + yStack.get(yStack.size() - 1 - 1));
+ }
+
+ public void move(int dx, int dy) {
+ dxStack.addLast(dx);
+ dyStack.addLast(dy);
+ xStack.addLast(xStack.getLast() + dx);
+ yStack.addLast(yStack.getLast() + dy);
+ }
+
+ public void moveX(int dx) {
+ move(dx, 0);
+ }
+
+ public void moveY(int dy) {
+ move(0, dy);
+ }
+
+ public void printCurrentCoordinates() {
+ System.out.println("current (x, y): " + xStack.peekLast() + " " + yStack.peekLast());
+ }
+
+ public void printLastCoordinates() {
+ int lastX = xStack.getLast() - dxStack.getLast();
+ int lastY = yStack.getLast() - dyStack.getLast();
+ System.out.println("last (x, y): " + lastX + " " + lastY);
+ }
+
+ public void printLastMove() {
+ int lastDx = dxStack.getLast();
+ int lastDy = dyStack.getLast();
+ System.out.println(
+ "last move: " + (lastDx == 0 ? "x" : lastDx) + " " + (lastDy == 0 ? "x" : lastDy));
+ }
+
+ public static void main(String[] args) {
+
+ Robot secondRobot = new Robot(2, 1);
+ secondRobot.moveX(1); // (2, 1) -> (3, 1)
+ secondRobot.printLastMove(); // (1, x)
+ secondRobot.printCurrentCoordinates(); // (3,1)
+ secondRobot.moveY(1); // (3, 1) - > (3, 2)
+ secondRobot.printLastCoordinates(); // (3, 1)
+ secondRobot.moveX(2); // (3,2) -> (5, 2)
+ secondRobot.printLastMove(); // (2, x)
+ secondRobot.printCurrentCoordinates(); // (5, 2)
+ secondRobot.moveY(0); // (5, 2) -> (5, 2)
+ secondRobot.printLastCoordinates(); // (5, 2)
+ }
+}
From aebacdad125b0a1315edf1756da416cfaf20b6cb Mon Sep 17 00:00:00 2001
From: Edward Tang <3278807+EdwardTang@users.noreply.github.com>
Date: Sat, 15 Feb 2020 12:10:45 -0800
Subject: [PATCH 4/6] solution without supporting numbers (#3)
* solution without supporting numbers
* vmware mock interview questions solution
* vmware-phone-2020-02 Solved find duplicates in file system
* code clean up
* add comments on problems
---
.../vmware/decodestr/DecodeAsciiString.java | 89 ++++++++++
.../vmware/finddup/FindDupInFileSystem.java | 47 +++++
.../company/vmware/hangman/HangmanSolver.java | 75 ++++++++
.../vmware/hangman/HangmanTrieNode.java | 12 ++
.../company/vmware/json/JsonValidator.java | 160 ++++++++++++++++++
.../com/company/vmware/myrand/MyRand.java | 46 +++++
.../com/company/vmware/{ => robot}/Robot.java | 2 +-
7 files changed, 430 insertions(+), 1 deletion(-)
create mode 100644 src/main/java/com/company/vmware/decodestr/DecodeAsciiString.java
create mode 100644 src/main/java/com/company/vmware/finddup/FindDupInFileSystem.java
create mode 100644 src/main/java/com/company/vmware/hangman/HangmanSolver.java
create mode 100644 src/main/java/com/company/vmware/hangman/HangmanTrieNode.java
create mode 100644 src/main/java/com/company/vmware/json/JsonValidator.java
create mode 100644 src/main/java/com/company/vmware/myrand/MyRand.java
rename src/main/java/com/company/vmware/{ => robot}/Robot.java (99%)
diff --git a/src/main/java/com/company/vmware/decodestr/DecodeAsciiString.java b/src/main/java/com/company/vmware/decodestr/DecodeAsciiString.java
new file mode 100644
index 0000000000..45779444f3
--- /dev/null
+++ b/src/main/java/com/company/vmware/decodestr/DecodeAsciiString.java
@@ -0,0 +1,89 @@
+package com.company.vmware.decodestr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * We encode a string, s, by performing the following sequence of actions:
+ *
+ * Replace each character with its ASCII value representation. Reverse the string. For example,
+ * the table below shows the conversion from the string "Go VMWare" to the ASCII string
+ * "711113286778797114101":
+ *
+ *
Character G o V M W a r e ASCII Value 71 111 32 86 77 87 97 114 101
+ *
+ *
We then reverse the ASCII string to get the encoded string 101411797877682311117. For
+ * reference, the characters in s are ASCII characters within the range 10 - 126 which include
+ * special characters. The function must decode the encoded string and return the list of ways in
+ * which s can be decoded.
+ *
+ *
// encoded - A reversed ASCII string denoting an encoded string s static Collection
+ * decode(String encoded) {
+ *
+ * return Collection }
+ */
+public class DecodeAsciiString {
+ public static List decode(String encoded) {
+ List ans = new ArrayList<>();
+
+ StringBuilder input1 = new StringBuilder();
+
+ // append a string into StringBuilder input1
+ input1.append(encoded);
+
+ // reverse StringBuilder input1
+ input1 = input1.reverse();
+
+ // print reversed String
+ // System.out.println(input1);
+
+ char[] encodedArr = encoded.toCharArray();
+
+ decodeHelper(0, encodedArr.length, new StringBuilder(), ans, input1.toString());
+
+ for (String s : ans) {
+ System.out.println(s);
+ }
+ return ans;
+ }
+
+ public static void decodeHelper(
+ int start, int length, StringBuilder sb, List ans, String encoded) {
+
+ if (start >= length - 1) {
+ ans.add(sb.toString());
+ return;
+ }
+ List splitList = new ArrayList<>();
+ if (start + 2 <= length) {
+ // get the first 2 chars of the string
+ splitList.add(encoded.substring(start, start + 2));
+ }
+ if (start + 3 <= length) {
+ // get the first 3 chars of the string
+ splitList.add(encoded.substring(start, start + 3));
+ }
+ // For each substring in splitList, check if it is valid ASCII value,
+ for (String each : splitList) {
+ if (isValid(each)) {
+ // System.out.println(each);
+ sb.append((char) (Integer.parseInt(each)));
+ decodeHelper(start + each.length(), length, sb, ans, encoded);
+ sb.setLength(sb.length() - 1); // back tracking
+ }
+ }
+ }
+
+ public static boolean isValid(String s) {
+ int val = Integer.parseInt(s);
+ return (val >= 10 && val <= 126);
+ }
+
+ public static void main(String[] args) {
+ System.out.println("Hello World!");
+ // String ss = "0018014111117811180180110127";
+ // decode(ss);
+ // decode("64101301011794019923111611236112117900179231116112312161150180150189792310140161123511501231019901110130150180180110161101137");
+ decode("101411797877682311117");
+ }
+}
diff --git a/src/main/java/com/company/vmware/finddup/FindDupInFileSystem.java b/src/main/java/com/company/vmware/finddup/FindDupInFileSystem.java
new file mode 100644
index 0000000000..a90d48eae5
--- /dev/null
+++ b/src/main/java/com/company/vmware/finddup/FindDupInFileSystem.java
@@ -0,0 +1,47 @@
+package com.company.vmware.finddup;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** Leetcode 609. Find Duplicate File in System */
+class FindDupInFileSystem {
+ // High level:
+ // 1. split the string into: pair of
+ // 2. use content as key, group all the pair into a hashmap: Map>
+ // 3. add the values of above hash map entries to a List> result
+ public List> findDuplicate(String[] paths) {
+ List> result = new ArrayList<>();
+ if (paths == null | paths.length == 0) {
+ return result;
+ }
+ Map> map = new HashMap<>();
+
+ for (String folder : paths) {
+ String[] folderSubstr = folder.split(" ");
+ mapAndGroup(map, folderSubstr);
+ }
+ map.entrySet().stream()
+ .filter(e -> (e.getValue() != null && e.getValue().size() > 1))
+ .forEach(
+ e -> {
+ result.add(e.getValue());
+ });
+ return result;
+ }
+
+ private void mapAndGroup(Map> map, String[] s) {
+ String dir = s[0];
+ for (int i = 1; i < s.length; i++) {
+ String[] metaData = s[i].split("\\(");
+ String fileName = metaData[0];
+ String content = metaData[1].substring(0, metaData[1].length() - 1);
+ String file = dir + "/" + fileName;
+ if (!map.containsKey(content)) {
+ map.put(content, new ArrayList<>());
+ }
+ map.get(content).add(file);
+ }
+ }
+}
diff --git a/src/main/java/com/company/vmware/hangman/HangmanSolver.java b/src/main/java/com/company/vmware/hangman/HangmanSolver.java
new file mode 100644
index 0000000000..d634c8dfb9
--- /dev/null
+++ b/src/main/java/com/company/vmware/hangman/HangmanSolver.java
@@ -0,0 +1,75 @@
+package com.company.vmware.hangman;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Design data structure for HangMan solver game. We are given array of lexocographically sorted
+ * strings 'dict[]' as input and a pattern 'puzzle', return list of all the words matching pattern
+ * 'puzzle'. 'puzzle' is a pattern containing underscore character "_".
+ *
+ * class HangmanSolver {
+ *
+ *
public HangmanSolver(String[] dict) { // todo }
+ *
+ *
public List solve(String puzzle) { // todo } } Here solve method could be called
+ * multiple times however HangManSolver() will be called only once. So the problem is to process
+ * strings in the input array and store in a data structure efficient for searching strings matching
+ * given pattern.
+ *
+ * Example:
+ *
+ *
HangmanSolver solver = new HangmanSolver(["ant", "feet", "meet", "zebra"]);
+ * solver.solve("_e_t"); // ["feet", "meet"]
+ */
+public class HangmanSolver {
+
+ private HangmanTrieNode root;
+
+ public HangmanSolver(List dict) {
+ root = new HangmanTrieNode(' ');
+ for (String word : dict) {
+ HangmanTrieNode ref = root;
+ for (char c : word.toCharArray()) {
+ ref.next[c - 'a'] = new HangmanTrieNode(c);
+ ref = ref.next[c - 'a'];
+ }
+ ref.word = word;
+ }
+ }
+
+ public List solve(String puzzle) {
+ List result = new ArrayList<>();
+ dfs(root, result, puzzle, 0);
+ return result;
+ }
+
+ private void dfs(HangmanTrieNode root, List result, String puzzle, int cur) {
+ // base case: no such char root in the dictionary
+ if (root == null || cur > puzzle.length()) {
+ return;
+ }
+ if (cur == puzzle.length()) {
+ if (root.word != null) {
+ result.add(root.word);
+ }
+ return;
+ }
+
+ char pChar = puzzle.charAt(cur);
+ if (pChar == '_') {
+ for (HangmanTrieNode next : root.next) {
+ dfs(next, result, puzzle, cur + 1);
+ }
+ } else {
+ dfs(root.next[pChar - 'a'], result, puzzle, cur + 1);
+ }
+ }
+
+ public static void main(String[] args) {
+ List dict1 = Arrays.asList(new String[] {"ant", "feet", "meet", "zebra"});
+ HangmanSolver solver1 = new HangmanSolver(dict1);
+ System.out.println(solver1.solve("_e_t").toString());
+ }
+}
diff --git a/src/main/java/com/company/vmware/hangman/HangmanTrieNode.java b/src/main/java/com/company/vmware/hangman/HangmanTrieNode.java
new file mode 100644
index 0000000000..fdb5e5a3c7
--- /dev/null
+++ b/src/main/java/com/company/vmware/hangman/HangmanTrieNode.java
@@ -0,0 +1,12 @@
+package com.company.vmware.hangman;
+
+public class HangmanTrieNode {
+ char val;
+ HangmanTrieNode[] next;
+ String word;
+
+ public HangmanTrieNode(char val) {
+ this.val = val;
+ this.next = new HangmanTrieNode[26];
+ }
+}
diff --git a/src/main/java/com/company/vmware/json/JsonValidator.java b/src/main/java/com/company/vmware/json/JsonValidator.java
new file mode 100644
index 0000000000..34b38c6ef9
--- /dev/null
+++ b/src/main/java/com/company/vmware/json/JsonValidator.java
@@ -0,0 +1,160 @@
+package com.company.vmware.json;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+/**
+ * Validate a json and return true or false.
+ */
+public class JsonValidator {
+
+ public static void main(String[] args) {
+ String test1 = "{}"; // true
+ String test2 = "{"; // false
+ String test3 = "{\"x\" : { \"y\" : \"z\"}}"; // true
+ String test4 =
+ "{ \n"
+ + " \"glossary\":{ \n"
+ + " \"title\":\"exampleglossary\",\n"
+ + " \"GlossDiv\":{ \n"
+ + " \"title\":\"S\",\n"
+ + " \"GlossList\":{ \n"
+ + " \"GlossEntry\":{ \n"
+ + " \"ID\":\"SGML\",\n"
+ + " \"SortAs\":\"SGML\",\n"
+ + " \"GlossTerm\":\"StandardGeneralizedMarkupLanguage\",\n"
+ + " \"Acronym\":\"SGML\",\n"
+ + " \"Abbrev\":\"ISO8879:1986\",\n"
+ + " \"GlossDef\":{ \n"
+ + " \"para\":\"Ameta-markuplanguage,usedtocreatemarkuplanguagessuchasDocBook.\",\n"
+ + " \"GlossSeeAlso\":[ \n"
+ + " \"GML\",\n"
+ + " \"XML\"\n"
+ + " ]\n"
+ + " },\n"
+ + " \"GlossSee\":\"markup\"\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + "}";
+ String test5 = "[{\n" + "\t\"\": \"\"\n" + "}]";
+ String test6 = "[\n" + "\t[]";
+ // assertTrue(isValid(test1));
+ // assertFalse(isValid(test2));
+ // assertTrue(isValid(test3));
+ assertTrue(isValid(test4));
+ assertTrue(isValid(test5));
+ assertFalse(isValid(test6));
+ }
+
+ public static boolean isValid(String s) {
+ Deque stack = new ArrayDeque<>();
+ char[] chars = s.toCharArray();
+ for (int i = 0; i < chars.length; i++) {
+ // TODO handle numeric values in json
+
+ // if(!stack.isEmpty() && stack.peekLast() == ':') {
+ // if(chars[i] == '"' || chars[i] == '{' || chars[i] == '[' ||
+ // Character.isDigit(chars[i])) {
+ // if(chars[i] == '"' || chars[i] == '{' || chars[i] == '['){
+ // stack.addLast(chars[i]);
+ // } else if (Character.isDigit(chars[i])) {
+ // if(chars[i] == '0'){
+ // stack.addLast(chars[i]);
+ // }
+ // }
+ // } else {
+ // // {"x" : a }
+ // System.out.println("processed: " + s.substring(0, i));
+ // System.out.println("chars[i]: " + chars[i]);
+ // return false;
+ // }
+ // } else if(!stack.isEmpty() && stack.peekLast() == '0') {
+ // if(chars[i] != '.') {
+ // System.out.println("processed: " + s.substring(0, i));
+ // System.out.println("chars[i]: " + chars[i]);
+ // return false;
+ // } else {
+ // stack.addLast(chars[i]);
+ // }
+ // } else if(!stack.isEmpty() && stack.peekLast() == '.') {
+ // if(!Character.isDigit(chars[i])) {
+ // return false;
+ // }
+ // } else if(isFocusSymbol(chars[i])) {
+
+ // Handle non-numeric values
+ if (isFocusSymbol(chars[i])) {
+ if (stack.isEmpty()) {
+ stack.addLast(chars[i]);
+ } else {
+ // stack is not empty
+ char top = stack.peekLast();
+ if (!isValidTop(top)) {
+ System.out.println("processed: " + s.substring(0, i));
+ System.out.println("chars[i]: " + chars[i]);
+ return false;
+ } else {
+ // top can be , { [ " :
+ if (top == '{') {
+ if (chars[i] == ']') {
+ System.out.println("processed: " + s.substring(0, i));
+ System.out.println("chars[i]: " + chars[i]);
+ return false;
+ } else if (chars[i] == '}') {
+ stack.removeLast();
+ } else {
+ stack.addLast(chars[i]);
+ }
+ } else if (top == '[') {
+ if (chars[i] == ':' || chars[i] == '}') {
+ System.out.println("processed: " + s.substring(0, i));
+ System.out.println("chars[i]: " + chars[i]);
+ return false;
+ } else if (chars[i] == ']') {
+ stack.removeLast();
+ } else {
+ stack.addLast(chars[i]);
+ }
+ } else if (top == ':' || top == ',') {
+ if (chars[i] == ']' || chars[i] == '}' || chars[i] == ',' || chars[i] == ':') {
+ System.out.println("processed: " + s.substring(0, i));
+ System.out.println("chars[i]: " + chars[i]);
+ return false;
+ } else {
+ // if (chars[i] == '{' || chars[i] == '[' || chars[i] == '"')
+ stack.removeLast();
+ stack.addLast(chars[i]);
+ }
+ } else {
+ // if (top == '"')
+ if (chars[i] == '"') {
+ stack.removeLast();
+ } else {
+ // skip any character inside the quotation mark
+ continue;
+ }
+ }
+ }
+ }
+ } else {
+ // skip literals
+ continue;
+ }
+ }
+ return stack.isEmpty();
+ }
+
+ private static boolean isFocusSymbol(char ch) {
+ return (ch == '{' || ch == '}' || ch == '[' || ch == ']' || ch == ':' || ch == ','
+ || ch == '"');
+ }
+
+ private static boolean isValidTop(char ch) {
+ return (ch == '{' || ch == '[' || ch == ':' || ch == ',' || ch == '"');
+ }
+}
diff --git a/src/main/java/com/company/vmware/myrand/MyRand.java b/src/main/java/com/company/vmware/myrand/MyRand.java
new file mode 100644
index 0000000000..4067e23db6
--- /dev/null
+++ b/src/main/java/com/company/vmware/myrand/MyRand.java
@@ -0,0 +1,46 @@
+package com.company.vmware.myrand;
+
+import java.util.StringJoiner;
+
+public final class MyRand {
+
+ /**
+ * Generate random decimal number between [5,55] inclusively with given rand_0() that randomly
+ * return 0 or 1;
+ *
+ * @return
+ */
+ public static int getRand() {
+
+ StringJoiner s = new StringJoiner("");
+ while (true) {
+ if (s.length() < 8) {
+ s.add(String.valueOf(oneOrZero()));
+ continue;
+ }
+
+ int v = Integer.parseInt(s.toString(), 2);
+
+ if (v >= 5 && v <= 55) {
+ return v;
+ } else {
+ s = new StringJoiner("");
+ }
+ }
+ }
+
+ /**
+ * rand_0() that randomly return 0 or 1
+ *
+ * @return
+ */
+ private static int oneOrZero() {
+ return (int) Math.round(Math.random());
+ }
+
+ public static void main(String[] args) {
+ for (int i = 0; i < 10; i++) {
+ System.out.println(MyRand.getRand());
+ }
+ }
+}
diff --git a/src/main/java/com/company/vmware/Robot.java b/src/main/java/com/company/vmware/robot/Robot.java
similarity index 99%
rename from src/main/java/com/company/vmware/Robot.java
rename to src/main/java/com/company/vmware/robot/Robot.java
index 9ed3ccc36d..2d4a390a0d 100644
--- a/src/main/java/com/company/vmware/Robot.java
+++ b/src/main/java/com/company/vmware/robot/Robot.java
@@ -1,4 +1,4 @@
-package com.company.vmware;
+package com.company.vmware.robot;
import java.util.LinkedList;
From 9088b34f9a7f68dc5eb20baf7cfee026f8224533 Mon Sep 17 00:00:00 2001
From: Edward Tang <3278807+EdwardTang@users.noreply.github.com>
Date: Thu, 5 Mar 2020 13:56:55 -0800
Subject: [PATCH 5/6] smartnews-onsite retrospective (#4)
* smartnews-onsite retrospective
* yoyo-phone-onsite
---
.../leet84/_84LargestRectangleHistogram.java | 72 ++++++++
.../leet84/uptake/_85MaxRectangleMatrix.java | 78 ++++++++
.../similar/_764LargestPlusSign.java | 73 ++++++++
.../onsite/DifferentWaysToAddParenthesis.java | 59 ++++++
.../company/smartnews/onsite/KthLargest.java | 164 +++++++++++++++++
.../smartnews/onsite/MergedKSortedArrays.java | 86 +++++++++
.../smartnews/onsite/MinSizeSubarraySum.java | 63 +++++++
.../smartnews/onsite/ShuffleArrays.java | 5 +
.../smartnews/onsite/TriangleNumber.java | 172 ++++++++++++++++++
.../smartnews/onsite/TriangleNumberII.java | 156 ++++++++++++++++
.../smartnews/onsite/ValidStackSequence.java | 69 +++++++
.../yoyo/onsite/MajorityElementVariant.java | 171 +++++++++++++++++
12 files changed, 1168 insertions(+)
create mode 100644 src/main/java/com/company/google/topmedium/leet84/_84LargestRectangleHistogram.java
create mode 100644 src/main/java/com/company/google/topmedium/leet84/uptake/_85MaxRectangleMatrix.java
create mode 100644 src/main/java/com/company/google/topmedium/maxsquare/similar/_764LargestPlusSign.java
create mode 100644 src/main/java/com/company/smartnews/onsite/DifferentWaysToAddParenthesis.java
create mode 100644 src/main/java/com/company/smartnews/onsite/KthLargest.java
create mode 100644 src/main/java/com/company/smartnews/onsite/MergedKSortedArrays.java
create mode 100644 src/main/java/com/company/smartnews/onsite/MinSizeSubarraySum.java
create mode 100644 src/main/java/com/company/smartnews/onsite/ShuffleArrays.java
create mode 100644 src/main/java/com/company/smartnews/onsite/TriangleNumber.java
create mode 100644 src/main/java/com/company/smartnews/onsite/TriangleNumberII.java
create mode 100644 src/main/java/com/company/smartnews/onsite/ValidStackSequence.java
create mode 100644 src/main/java/com/company/yoyo/onsite/MajorityElementVariant.java
diff --git a/src/main/java/com/company/google/topmedium/leet84/_84LargestRectangleHistogram.java b/src/main/java/com/company/google/topmedium/leet84/_84LargestRectangleHistogram.java
new file mode 100644
index 0000000000..077529c43e
--- /dev/null
+++ b/src/main/java/com/company/google/topmedium/leet84/_84LargestRectangleHistogram.java
@@ -0,0 +1,72 @@
+package com.company.google.topmedium.leet84;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Deque;
+import java.util.LinkedList;
+
+public class _84LargestRectangleHistogram {
+
+ /**
+ * Leetcode 84: Largest Rectangle in histograms
+ *
+ * Given n non-negative integers representing the histogram's bar height where the width of
+ * each bar is 1, find the area of largest rectangle in the histogram.
+ *
+ *
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]. The largest
+ * rectangle is shown in the shaded area, which has area = 10 unit.
+ *
+ *
For example, Given heights = [2,1,5,6,2,3], return 10.
+ *
+ *
C:
+ *
+ *
What is maximum area supported in this quesiont? Within Integer' data range
+ *
+ *
Is there any negative height? A:
+ *
+ *
assume the maximum area is less than Integer.MAX_VALUE
+ *
+ *
R:
+ *
+ *
Use a stack to maintain a series of monolithtic increasing histrograms's index. Only
+ * monolithtic increasing histogram can produce more rectangle area.
+ *
+ *
When we meet decrease histogram: heights[i - 1] > heights[i], pop the stack top, and
+ * calculate the area with the following formula: area = (i - stock[top - 1] - 1) *
+ * heights[stack[top]] T:
+ *
+ *
null, empty -> 0
+ *
+ *
[1,2,3,4] -> 6
+ *
+ *
[1,2,3,4,3] -> 9
+ *
+ *
[3,2,1] -> 4
+ */
+ public static int largestRectangleArea(int[] heights) {
+ if (heights == null || heights.length == 0) {
+ return 0;
+ }
+ Deque stack = new LinkedList<>();
+ int maxArea = 0;
+ for (int i = 0; i <= heights.length; i++) {
+ int cur = (i == heights.length) ? 0 : heights[i];
+ while (!stack.isEmpty() && heights[stack.peekLast()] >= cur) {
+ int height = heights[stack.pollLast()];
+ int left = stack.isEmpty() ? 0 : stack.peekLast() + 1;
+ maxArea = Math.max(maxArea, height * (i - left));
+ }
+ stack.addLast(i);
+ }
+ return maxArea;
+ }
+
+ public static void main(String[] args) {
+ assertEquals(0, largestRectangleArea(null));
+ assertEquals(0, largestRectangleArea(new int[] {}));
+ assertEquals(1, largestRectangleArea(new int[] {1}));
+ assertEquals(6, largestRectangleArea(new int[] {1, 2, 3, 4}));
+ assertEquals(9, largestRectangleArea(new int[] {1, 2, 3, 4, 3}));
+ assertEquals(4, largestRectangleArea(new int[] {3, 2, 1}));
+ }
+}
diff --git a/src/main/java/com/company/google/topmedium/leet84/uptake/_85MaxRectangleMatrix.java b/src/main/java/com/company/google/topmedium/leet84/uptake/_85MaxRectangleMatrix.java
new file mode 100644
index 0000000000..85ff1862b5
--- /dev/null
+++ b/src/main/java/com/company/google/topmedium/leet84/uptake/_85MaxRectangleMatrix.java
@@ -0,0 +1,78 @@
+package com.company.google.topmedium.leet84.uptake;
+
+
+import static com.company.google.topmedium.leet84._84LargestRectangleHistogram.largestRectangleArea;
+import static org.junit.Assert.assertEquals;
+
+public class _85MaxRectangleMatrix {
+
+ /**
+ * 85. Maximal Rectangle
+ *
+ * Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only
+ * 1's and return its area.
+ *
+ *
For example, given the following matrix:
+ *
+ *
1 0 1 0 0
+ * 1 0 1 1 1
+ * 1 1 1 1 1
+ * 1 0 0 1 0
+ *
+ * Return 6.
+ *
C:
+ *
+ *
What is the data type of the elements? char or int? -> char
+ *
+ *
How big can the matrix be? The area of the matrix can be fit into memory A:
+ *
+ *
The matrix cannot be null/ empty., and at least has one element. R:
+ *
+ *
1. rows as X axis, and columns as Y axis. The 1 rectangle can be considered as the a series
+ * of histograms based on current row
+ *
+ *
Thus the matrix can be converted to 4 histograms:
+ *
+ *
1st row: [1, 0 , 1, 0, 0]
+ *
+ *
2nd row: [2, 0 , 2, 1, 1]
+ *
+ *
3rd row: [3, 1 , 3, 2, 2]
+ *
+ *
4th row: [4, 0 , 0, 3, 0]
+ *
+ *
2. Apply the monolithic increasing stack to get the max area among the histogram
+ * T:
[[1]], problem example
+ */
+
+ public static int maxRetangleArea(char[][] A) {
+ int[][] H = new int[A.length][A[0].length];
+ for (int row = 0; row < A.length; row++) {
+ for (int col = 0; col < A[0].length; col++) {
+ if (row == 0) {
+ H[row][col] = (A[row][col] - '0');
+ } else {
+ H[row][col] = (A[row][col] - '0') == 0 ? 0 : (H[row - 1][col]) + 1;
+ }
+ }
+ }
+ int maxArea = 0;
+ for (int[] heights : H) {
+ maxArea = Math.max(maxArea, largestRectangleArea(heights));
+ }
+ return maxArea;
+ }
+
+ public static void main(String[] args) {
+ char[][] test1 = new char[][] {{'1'}};
+ char[][] test2 =
+ new char[][] {
+ {'1', '0', '1', '0', '0'},
+ {'1', '0', '1', '1', '1'},
+ {'1', '1', '1', '1', '1'},
+ {'1', '0', '0', '1', '0'}
+ };
+ assertEquals(1, maxRetangleArea(test1));
+ assertEquals(6, maxRetangleArea(test2));
+ }
+}
diff --git a/src/main/java/com/company/google/topmedium/maxsquare/similar/_764LargestPlusSign.java b/src/main/java/com/company/google/topmedium/maxsquare/similar/_764LargestPlusSign.java
new file mode 100644
index 0000000000..eaa2acc2c8
--- /dev/null
+++ b/src/main/java/com/company/google/topmedium/maxsquare/similar/_764LargestPlusSign.java
@@ -0,0 +1,73 @@
+package com.company.google.topmedium.maxsquare.similar;
+
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+class _764LargestPlusSign {
+
+ /**
+ * In a 2D grid from (0, 0) to (N-1, N-1), every cell contains a 1, except those cells in the
+ * given list mines which are 0. What is the largest axis-aligned plus sign of 1s contained in the
+ * grid? Return the order of the plus sign. If there is none, return 0.
+ *
+ *
An "axis-aligned plus sign of 1s of order k" has some center grid[x][y] = 1 along with 4
+ * arms of length k-1 going up, down, left, and right, and made of 1s. This is demonstrated in the
+ * diagrams below. Note that there could be 0s or 1s beyond the arms of the plus sign, only the
+ * relevant area of the plus sign is checked for 1s.
+ *
+ *
Input: N = 5, mines = [[4, 2]] Output: 2 Explanation: 11111 11111 11111 11111 11011 In the
+ * above grid, the largest plus sign can only be order 2.
+ */
+ public static int orderOfLargestPlusSign(int N, int[][] mines) {
+ int[][] dp = new int[N][N];
+
+ for (int[] row : dp) {
+ Arrays.fill(row, N);
+ }
+
+ for (int[] m : mines) {
+ dp[m[0]][m[1]] = 0;
+ }
+
+ for (int i = 0; i < N; i++) {
+
+ int left = 0;
+ for (int j = 0; j < N; j++) {
+ left = dp[i][j] == 0 ? 0 : left + 1;
+ dp[i][j] = Math.min(dp[i][j], left);
+ }
+
+ int right = 0;
+ for (int j = N - 1; j >= 0; j--) {
+ right = dp[i][j] == 0 ? 0 : right + 1;
+ dp[i][j] = Math.min(dp[i][j], right);
+ }
+
+ int top = 0;
+ for (int j = 0; j < N; j++) {
+ top = dp[j][i] == 0 ? 0 : top + 1;
+ dp[j][i] = Math.min(dp[j][i], top);
+ }
+
+ int bottom = 0;
+ for (int j = N - 1; j >= 0; j--) {
+ bottom = dp[j][i] == 0 ? 0 : bottom + 1;
+ dp[j][i] = Math.min(dp[j][i], bottom);
+ }
+ }
+
+ int res = 0;
+ for (int i = 0; i < N; i++) {
+ for (int j = 0; j < N; j++) {
+ res = Math.max(res, dp[i][j]);
+ }
+ }
+ return res;
+ }
+
+ public static void main(String[] args) {
+ assertEquals(2, orderOfLargestPlusSign(5, new int[][] {{4, 2}}));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/company/smartnews/onsite/DifferentWaysToAddParenthesis.java b/src/main/java/com/company/smartnews/onsite/DifferentWaysToAddParenthesis.java
new file mode 100644
index 0000000000..7d4220179b
--- /dev/null
+++ b/src/main/java/com/company/smartnews/onsite/DifferentWaysToAddParenthesis.java
@@ -0,0 +1,59 @@
+package com.company.smartnews.onsite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DifferentWaysToAddParenthesis {
+
+ public static void main(String[] args) {
+ String test1 = "2-1-1";
+ System.out.println(findWays(test1).toString());
+ String test2 = "2*3-4*5";
+ System.out.println(findWays(test2).toString());
+ }
+
+ public static List findWays(String input) {
+ String[] nums = input.split("[*,+,-]");
+ char[] operators = input.replaceAll("[0-9]", "").toCharArray();
+ List[][] mem = new List[nums.length][nums.length];
+ return dfs(nums, operators, 0, nums.length - 1, mem);
+ }
+
+ private static List dfs(
+ String[] nums, char[] operators, int start, int end, List[][] mem) {
+ if (mem[start][end] != null) {
+ return mem[start][end];
+ }
+
+ if (start == end) {
+ List baseCase = new ArrayList<>();
+ baseCase.add(Integer.parseInt(nums[start]));
+ mem[start][end] = baseCase;
+ return baseCase;
+ }
+
+ List result = new ArrayList<>();
+ for (int k = start; k < end; k++) {
+ List group1 = dfs(nums, operators, start, k, mem);
+ List group2 = dfs(nums, operators, k + 1, end, mem);
+ for (Integer num1 : group1) {
+ for (Integer num2 : group2) {
+ result.add(calcuate(operators[k], num1, num2));
+ }
+ }
+ }
+ mem[start][end] = result;
+ return result;
+ }
+
+ private static Integer calcuate(char operator, Integer nums1, Integer nums2) {
+ switch (operator) {
+ case '*':
+ return nums1 * nums2;
+ case '+':
+ return nums1 + nums2;
+ default:
+ return nums1 - nums2;
+ }
+ }
+}
diff --git a/src/main/java/com/company/smartnews/onsite/KthLargest.java b/src/main/java/com/company/smartnews/onsite/KthLargest.java
new file mode 100644
index 0000000000..1e6bfb3e47
--- /dev/null
+++ b/src/main/java/com/company/smartnews/onsite/KthLargest.java
@@ -0,0 +1,164 @@
+package com.company.smartnews.onsite;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.PriorityQueue;
+
+public class KthLargest {
+
+ public static void main(String[] args) {
+ // int[] nums1 = new int[]{3,2,5,1,4};
+ // assertTrue(4 == maxHeapSolution(nums1, 2));
+ // assertTrue(4 == minHeapSolution(nums1, 2));
+ // assertTrue(4 == quickSelectSolution(nums1, 2));
+
+ int[] nums2 =
+ new int[]{
+ 15, 44, 16, 43, 47, 47, 45, 27, 46, 2, 28, 12, 49, 22, 36, 12, 6, 48, 28, 19, 18, 34,
+ 46,
+ 38, 42, 3, 21, 3, 54, 35, 21, 54, 13, 46, 50, 23, 53, 43, 5, 48, 40, 48, 10, 31, 15, 35,
+ 50, 8, 48, 55, 52, 18, 54, 16, 35, 4, 43, 55, 34, 13, 5, 13, 27, 41, 19, 22, 21, 26, 48,
+ 4, 15, 1, 45, 51, 13, 49, 22, 33, 18, 18, 52, 27, 6, 41, 7, 11, 48, 17, 37, 31, 42, 3,
+ 45,
+ 22, 6, 45, 42, 5, 28, 39, 35, 30, 24, 21, 49, 49, 47, 54, 28, 42, 40, 26, 47, 8, 28, 1,
+ 44, 4, 45, 23, 49, 53, 12, 48, 16, 27, 36, 21, 18, 41, 43, 9, 55, 27, 37, 41, 5, 43, 12,
+ 45, 0, 34, 19, 48, 14, 22, 43, 14, 13, 38, 15, 7, 41, 8, 37, 13, 45, 31, 47, 38, 45, 38,
+ 50, 44, 20, 40, 39, 38, 26, 29, 24, 10, 30, 23, 53, 38, 39, 3, 37, 4, 15, 22, 29, 4, 5,
+ 4,
+ 4, 19, 35, 30, 30, 49, 16, 32, 36, 26, 37, 53, 46, 28, 24, 13, 12, 29, 2, 36, 21, 19,
+ 15,
+ 11, 22, 10, 30, 29, 40, 14, 17, 39, 36, 17, 23, 39, 13, 29, 51, 8, 55, 10, 10, 47, 39,
+ 1,
+ 46, 27, 18, 7, 49, 38, 27, 14, 26, 35, 5, 46, 54, 12, 18, 30, 11, 6, 29, 52, 44, 38, 51,
+ 22, 26, 24, 41, 13, 39, 27, 0, 36, 38, 7, 37, 7, 9, 25, 4, 8, 52, 33, 46, 33, 42, 43,
+ 17,
+ 23, 20, 23, 41, 8, 47, 16, 48, 46, 35, 35, 24, 0, 17, 12, 40, 52, 11, 16, 7, 33, 6, 21,
+ 30, 32, 55, 52, 52, 28, 11, 35, 39, 15, 27, 47, 52, 0, 11, 41, 50, 10, 13, 10, 5, 40,
+ 21,
+ 0, 27, 12, 39, 20, 27, 39, 19, 28, 5, 51, 45, 19, 3, 1, 15, 53, 31, 45, 36, 33, 22, 4,
+ 22,
+ 20, 30, 7, 54, 13, 19, 48, 32, 13, 38, 9, 4, 22, 26, 22, 43, 5, 47, 14, 15, 21, 15, 48,
+ 10, 15, 47, 22, 9, 52, 4, 16, 22, 47, 9, 13, 44, 15, 5, 19, 2, 55, 36, 49, 25, 52, 21,
+ 5,
+ 19, 46, 2, 51, 45, 12, 54, 47, 47, 23, 17, 26, 52, 36, 49, 4, 42, 18, 20, 22, 47, 18,
+ 37,
+ 28, 19, 11, 21, 13, 37, 51, 2, 43, 36, 43, 0, 40, 50, 27, 40, 41, 31, 41, 53, 2, 17, 4,
+ 35, 52, 22, 25, 21, 16, 5, 41, 54, 5, 40, 3, 38, 12, 10, 53, 48, 28, 9, 7, 46, 28, 3, 9,
+ 44, 29, 39, 3, 41, 15, 29, 30, 47, 21, 12, 27, 53, 7, 34, 53, 53, 50, 53, 23, 46, 52,
+ 40,
+ 21, 3, 46, 49, 17, 14, 36, 10, 54, 51, 22, 25, 34, 49, 49, 26, 45, 45, 17, 30, 19, 6,
+ 49,
+ 41, 9, 19, 25, 51, 23, 55, 11, 0, 1, 13, 26, 15, 41, 38, 19, 51, 21, 11, 8, 55, 25, 21,
+ 15, 18, 15, 48, 4, 37, 36, 5, 45, 13, 13, 16, 26, 0, 41, 8, 51, 20, 38, 28, 46, 3, 37,
+ 52,
+ 6, 24, 11, 18, 39, 25, 48, 16, 41, 50, 44, 48, 7, 29, 14, 15, 28, 7, 46, 15, 16, 46, 20,
+ 35, 6, 27, 10, 17, 1, 42, 30, 37, 41, 37, 52, 55, 4, 6, 17, 27, 33, 45, 37, 11, 29, 16,
+ 42, 33, 39, 35, 33, 30, 25, 37, 6, 25, 22, 43, 31, 42, 25, 15, 27, 19, 15, 10, 1, 45,
+ 24,
+ 23, 17, 17, 33, 12, 53, 30, 44, 30, 2, 30, 8, 45, 49, 48, 46, 52, 13, 41, 29, 46, 39,
+ 50,
+ 51, 19, 55, 36, 29, 23, 8, 11, 49, 43, 45, 51, 2, 41, 53, 6, 38, 52, 26, 45, 0, 55, 14,
+ 42, 25, 10, 4, 39, 5, 47, 42, 55, 37, 35, 53, 14, 27, 54, 41, 19, 34, 38, 43, 22, 41,
+ 23,
+ 12, 13, 17, 36, 23, 41, 15, 34, 24, 44, 21, 3, 25, 10, 14, 43, 16, 35, 45, 1, 22, 26,
+ 20,
+ 5, 8, 37, 42, 47, 1, 2, 33, 2, 21, 8, 36, 50, 6, 45, 40, 48, 16, 12, 1, 55, 0, 53, 51,
+ 35,
+ 19, 14, 3, 21, 33, 2, 54, 33, 2, 18, 53, 34, 19, 23, 32, 27, 39, 13, 48, 27, 12, 7, 50,
+ 16, 49, 35, 27, 12, 29, 6, 34, 7, 18, 50, 6, 49, 24, 1, 18, 53, 27, 36, 0, 37, 42, 51,
+ 12,
+ 38, 8, 29, 38, 11, 24, 4, 2, 15, 19, 1, 25, 9, 30, 50, 30, 8, 15, 50, 52, 25, 8, 29, 44,
+ 7, 41, 30, 45, 9, 23, 20, 49, 15, 16, 48, 34, 10, 44, 52, 22, 4, 6, 2, 8, 23, 13, 39, 7,
+ 31, 29, 4, 35, 43, 2, 33, 34, 24, 41, 38, 47, 5, 38, 28, 34, 1, 44, 14, 13, 12, 8, 6, 0,
+ 24, 9, 4, 39, 37, 32, 18, 38, 15, 29, 14, 11, 40, 34, 12, 16, 7, 7, 50, 18, 24, 30, 15,
+ 13, 41, 42, 47, 22, 17, 14, 38, 46, 45, 22, 12, 12, 12, 25, 11, 24, 41, 8, 51, 51, 25,
+ 46,
+ 15, 13, 47, 38, 20, 0, 21, 7, 30, 49, 42, 43, 53, 24, 19, 17, 46, 50, 15, 33, 1, 42, 14,
+ 55, 26, 17, 41, 39, 23, 46, 35, 39, 16, 16, 37, 50, 38, 24, 20, 32, 51, 22, 53, 50, 10,
+ 39, 4, 2, 27, 1, 25, 18, 40, 50, 9, 35, 37, 27, 37, 39, 29, 2, 38, 32, 6, 30, 32, 4, 43,
+ 46, 21, 9, 40, 45, 49, 34, 37, 4, 55, 19, 47, 3, 42, 33, 13, 43, 3, 3, 22, 49
+ };
+ int minHeapResult = minHeapSolution(nums2, 5);
+ System.out.println("minHeap Result: " + minHeapResult);
+ assertTrue(minHeapResult == maxHeapSolution(nums2, 5));
+ assertTrue(minHeapResult == quickSelectSolution(nums2, 5));
+ }
+
+ // Time: (n + k)logn, Space o(n)
+ public static Integer maxHeapSolution(int[] nums, int k) {
+ PriorityQueue maxHeap = new PriorityQueue<>(11, Collections.reverseOrder());
+ for (int i = 0; i < nums.length; i++) { // nlogn
+ maxHeap.offer(nums[i]);
+ }
+ while (k > 1) { // k*logn
+ maxHeap.poll();
+ k--;
+ }
+ return maxHeap.peek();
+ }
+
+ // Time( k*logk + (n - k)* 2*logK = (2n-k)logk = O(n-k)logk, Space O(K)
+ public static Integer minHeapSolution(int[] nums, int k) {
+ PriorityQueue minHeap = new PriorityQueue<>();
+ for (int i = 0; i < nums.length; i++) {
+ if (i < k) { // k
+ minHeap.offer(nums[i]); // logk
+ } else {
+ if (nums[i] > minHeap.peek()) { // (n-k)
+ minHeap.poll(); // logK
+ minHeap.offer(nums[i]); // logK
+ }
+ }
+ }
+ return minHeap.peek();
+ }
+
+ public static int quickSelectSolution(int[] nums, int k) {
+ int n = nums.length;
+ quickSelect(nums, 0, n - 1, n - k); // K-th largest == (N - K)-th smallest
+ return nums[n - k];
+ }
+
+ // Time: O(N) Space:O(logN)
+ private static void quickSelect(int[] nums, int left, int right, int target) {
+ int mid = partition(nums, left, right);
+ if (mid == target) {
+ return;
+ } else if (mid < target) {
+ quickSelect(nums, mid + 1, right, target);
+ } else { // mid > target
+ quickSelect(nums, left, mid - 1, target);
+ }
+ }
+
+ private static int partition(int[] nums, int left, int right) {
+ int pivotIndex = pivotIndex(left, right);
+ mySwap(nums, pivotIndex, right);
+ int pivot = nums[right];
+ int start = left;
+ int end = right - 1;
+ while (start <= end) {
+ if (nums[start] < pivot) {
+ start++;
+ } else if (nums[end] >= pivot) {
+ end--;
+ } else {
+ mySwap(nums, start++, end--);
+ }
+ }
+ mySwap(nums, start, right);
+ return start;
+ }
+
+ private static int pivotIndex(int left, int right) {
+ int pivotIndnex = left + (int) (Math.random() * (right - left + 1));
+ return pivotIndnex;
+ }
+
+ private static void mySwap(int[] nums, int left, int right) {
+ int tmp = nums[left];
+ nums[left] = nums[right];
+ nums[right] = tmp;
+ }
+}
diff --git a/src/main/java/com/company/smartnews/onsite/MergedKSortedArrays.java b/src/main/java/com/company/smartnews/onsite/MergedKSortedArrays.java
new file mode 100644
index 0000000000..620c18335a
--- /dev/null
+++ b/src/main/java/com/company/smartnews/onsite/MergedKSortedArrays.java
@@ -0,0 +1,86 @@
+package com.company.smartnews.onsite;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import java.util.Comparator;
+import java.util.PriorityQueue;
+
+/**
+ * LaiCode 133. Merge K Sorted Array Medium Merge K sorted array into one big sorted array in
+ * ascending order.
+ *
+ * Assumptions
+ *
+ *
The input arrayOfArrays is not null, none of the arrays is null either.
+ */
+public class MergedKSortedArrays {
+
+ public static void main(String[] args) {
+ MergedKSortedArrays sol = new MergedKSortedArrays();
+
+ int[][] test1 = new int[][]{{}, {1, 5, 7}, {4}, {2, 3, 5, 11}, {2, 4, 4, 6, 8}};
+ int[] expected1 = new int[]{1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 7, 8, 11};
+ assertArrayEquals(sol.merge(test1), expected1);
+
+ int[][] test2 = new int[][]{{1, 1, 1}, {2, 2, 2}, {3, 3, 3}, {1, 2, 3}};
+ int[] expected2 = new int[]{1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3};
+ assertArrayEquals(sol.merge(test2), expected2);
+ }
+
+ public int[] merge(int[][] arrayOfArrays) {
+ // Write your solution here
+ // Assumptions: arrayOfArrays is not
+ PriorityQueue minHeap = new PriorityQueue(11, new MyComparator());
+ int length = 0;
+ for (int i = 0; i < arrayOfArrays.length; i++) {
+ int[] array = arrayOfArrays[i];
+ length += array.length;
+ if (array.length != 0) {
+ // We use two index to record the position of each element:
+ // the index of the array in the arrayOfArrays,
+ // the index of the element in the array.
+ minHeap.offer(new Entry(i, 0, array[0]));
+ }
+ }
+ int[] result = new int[length];
+ int cur = 0;
+ while (!minHeap.isEmpty()) {
+ Entry tmp = minHeap.poll();
+ result[cur++] = tmp.value;
+ if (tmp.y + 1 < arrayOfArrays[tmp.x].length) {
+ // reuse the same entry object but advance the index by 1.
+ tmp.y++;
+ tmp.value = arrayOfArrays[tmp.x][tmp.y];
+ minHeap.offer(tmp);
+ }
+ }
+ return result;
+ }
+
+ static class MyComparator implements Comparator {
+
+ @Override
+ public int compare(Entry e1, Entry e2) {
+ if (e1.value == e2.value) {
+ return 0;
+ }
+ return e1.value < e2.value ? -1 : 1;
+ }
+ }
+
+ static class Entry {
+
+ // the row number
+ int x;
+ // the column number
+ int y;
+ // the corresponding value
+ int value;
+
+ Entry(int x, int y, int value) {
+ this.x = x;
+ this.y = y;
+ this.value = value;
+ }
+ }
+}
diff --git a/src/main/java/com/company/smartnews/onsite/MinSizeSubarraySum.java b/src/main/java/com/company/smartnews/onsite/MinSizeSubarraySum.java
new file mode 100644
index 0000000000..0686de919a
--- /dev/null
+++ b/src/main/java/com/company/smartnews/onsite/MinSizeSubarraySum.java
@@ -0,0 +1,63 @@
+package com.company.smartnews.onsite;
+
+import static org.junit.Assert.assertEquals;
+
+public class MinSizeSubarraySum {
+
+ /**
+ * LeetCode 209: Minimum Size Subarray Sum
+ * C:
+ * What is the value range of the element in the array? Is negative number allow?
+ * What is sum range of the array?
+ *
+ * A:
+ * We can assume that the sum range of the array is less than Integer.MAX_VALUE
+ * The element is always positive in the array, all element is integer
+ * If the input array is null, empty, or target not found, return -1
+ * R:
+ * 1. Use two pointer start and end initially points at the beginning of the array
+ * 2.1 The semantics of start pointer: the left side of start pointer is the element we have
+ * processed and left behind>
+ *
2.2 The semantics of end pointer: the left side (include the pointer) of end pointer is the
+ * elements that we can keep in the subarray whose sum is >= target,
+ * the right side fo the end pointer are the elements we are about to process
+ * 3.1 When the sum of subarray between start and end is less than target, expand the subarray
+ * by moving end pointer until we found the sum >= target>
+ *
3.2 When we found the sum >= target, record and update the min size, update the sum by
+ * reducing what start pointer points, move the start pointer to shorten the subarray, until the
+ * sum is < target
+ * 3.3 keep doing 3.1 and 3.2 until end == length of nums
+ * T:
+ * null, empty -> -1
+ * [1,2], t = 7 -> -1
+ * [2,1,3,2,7] t = 7 -> 1
+ * [2,1,3,2] t = 5 -> 2
+ */
+
+ public static int minSize(int[] nums, int target) {
+ if (nums == null || nums.length == 0 || target <= 0) {
+ return -1;
+ }
+ int res = Integer.MAX_VALUE;
+ int sum = 0;
+ int start = 0;
+ for (int end = 0; end < nums.length; end++) {
+ sum += nums[end];
+ while (sum >= target && start <= end) {
+ res = Math.min(res, end - start + 1);
+ sum -= nums[start++];
+ }
+ }
+ return res == Integer.MAX_VALUE ? -1 : res;
+ }
+
+ public static void main(String[] args) {
+ assertEquals(-1, minSize(null, 7));
+ assertEquals(-1, minSize(new int[]{}, 7));
+ assertEquals(-1, minSize(new int[]{1, 2}, 7));
+ assertEquals(1, minSize(new int[]{2, 1, 3, 2, 7}, 7));
+ assertEquals(2, minSize(new int[]{2, 1, 3, 2}, 5));
+
+ }
+
+}
diff --git a/src/main/java/com/company/smartnews/onsite/ShuffleArrays.java b/src/main/java/com/company/smartnews/onsite/ShuffleArrays.java
new file mode 100644
index 0000000000..fed28734fa
--- /dev/null
+++ b/src/main/java/com/company/smartnews/onsite/ShuffleArrays.java
@@ -0,0 +1,5 @@
+package com.company.smartnews.onsite;
+
+public class ShuffleArrays {
+
+}
diff --git a/src/main/java/com/company/smartnews/onsite/TriangleNumber.java b/src/main/java/com/company/smartnews/onsite/TriangleNumber.java
new file mode 100644
index 0000000000..9febf44e36
--- /dev/null
+++ b/src/main/java/com/company/smartnews/onsite/TriangleNumber.java
@@ -0,0 +1,172 @@
+package com.company.smartnews.onsite;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Leetcode 611. Valid Triangle Number Medium
+ *
+ * Share Given an array consists of non-negative integers, your task is to count the number of
+ * triplets chosen from the array that can make triangles if we take them as side lengths of a
+ * triangle.
+ *
+ *
Example 1:
+ *
+ *
Input: [2,2,3,4]
+ *
+ *
Output: 3
+ *
+ *
Explanation:
+ *
+ *
Valid combinations are:
+ *
+ *
2,3,4 (using the first 2)
+ *
+ *
2,3,4 (using the second 2)
+ *
+ *
2,2,3
+ */
+public class TriangleNumber {
+
+ // O(n^2)
+ public int triangleNumber(int[] nums) {
+ if (nums.length < 3) {
+ return 0;
+ }
+ int n = nums.length;
+ Arrays.sort(nums); // nlogn
+ int ans = 0;
+ /*
+ i 0 1 2 3
+ nums 2 2 3 4
+ c
+ b
+ a
+ ans += 2 - 0, ans = 2
+ >>>>>>>>>>>>>>>>>>>>>>
+ i 0 1 2 3
+ nums 2 2 3 4
+ c
+ b
+ a
+ ans remains 2
+ >>>>>>>>>>>>>>>>>>>>>>
+ i 0 1 2 3
+ nums 2 2 3 4
+ c
+ b
+ a
+ ans remains 2
+ >>>>>>>>>>>>>>>>>>>>>
+ i 0 1 2 3
+ nums 2 2 3 4
+ c
+ b
+ a
+ ans += 1, ans = 3
+ >>>>>>>>>>>>>>>>>>>>>
+ */
+// Set> results = new HashSet<>();
+ for (int c = n - 1; c > 1; c--) { // n iteration
+ int b = c - 1;
+ int a = 0;
+ while (a < b) { // n iteration
+ if (nums[a] + nums[b] > nums[c]) {
+ ans += b - a;
+// collect(results, nums, a, b, c);
+ b--;
+ } else {
+ a++;
+ }
+ }
+ }
+// System.out.println(results.toString());
+ return ans;
+ }
+
+ private void collect(Set> results, int[] nums, int a, int b, int c) {
+ for (int i = a; i < b; i++) {
+ List result = new ArrayList<>();
+ result.add(nums[a]);
+ result.add(nums[b]);
+ result.add(nums[c]);
+ results.add(result);
+ }
+ }
+
+ public static void main(String[] args) {
+ TriangleNumber sol = new TriangleNumber();
+ int[] test1 = new int[]{2, 2, 3, 4};
+ int[] test2 =
+ new int[]{
+ 15, 44, 16, 43, 47, 47, 45, 27, 46, 2, 28, 12, 49, 22, 36, 12, 6, 48, 28, 19, 18, 34,
+ 46,
+ 38, 42, 3, 21, 3, 54, 35, 21, 54, 13, 46, 50, 23, 53, 43, 5, 48, 40, 48, 10, 31, 15, 35,
+ 50, 8, 48, 55, 52, 18, 54, 16, 35, 4, 43, 55, 34, 13, 5, 13, 27, 41, 19, 22, 21, 26, 48,
+ 4, 15, 1, 45, 51, 13, 49, 22, 33, 18, 18, 52, 27, 6, 41, 7, 11, 48, 17, 37, 31, 42, 3,
+ 45,
+ 22, 6, 45, 42, 5, 28, 39, 35, 30, 24, 21, 49, 49, 47, 54, 28, 42, 40, 26, 47, 8, 28, 1,
+ 44, 4, 45, 23, 49, 53, 12, 48, 16, 27, 36, 21, 18, 41, 43, 9, 55, 27, 37, 41, 5, 43, 12,
+ 45, 0, 34, 19, 48, 14, 22, 43, 14, 13, 38, 15, 7, 41, 8, 37, 13, 45, 31, 47, 38, 45, 38,
+ 50, 44, 20, 40, 39, 38, 26, 29, 24, 10, 30, 23, 53, 38, 39, 3, 37, 4, 15, 22, 29, 4, 5,
+ 4,
+ 4, 19, 35, 30, 30, 49, 16, 32, 36, 26, 37, 53, 46, 28, 24, 13, 12, 29, 2, 36, 21, 19,
+ 15,
+ 11, 22, 10, 30, 29, 40, 14, 17, 39, 36, 17, 23, 39, 13, 29, 51, 8, 55, 10, 10, 47, 39,
+ 1,
+ 46, 27, 18, 7, 49, 38, 27, 14, 26, 35, 5, 46, 54, 12, 18, 30, 11, 6, 29, 52, 44, 38, 51,
+ 22, 26, 24, 41, 13, 39, 27, 0, 36, 38, 7, 37, 7, 9, 25, 4, 8, 52, 33, 46, 33, 42, 43,
+ 17,
+ 23, 20, 23, 41, 8, 47, 16, 48, 46, 35, 35, 24, 0, 17, 12, 40, 52, 11, 16, 7, 33, 6, 21,
+ 30, 32, 55, 52, 52, 28, 11, 35, 39, 15, 27, 47, 52, 0, 11, 41, 50, 10, 13, 10, 5, 40,
+ 21,
+ 0, 27, 12, 39, 20, 27, 39, 19, 28, 5, 51, 45, 19, 3, 1, 15, 53, 31, 45, 36, 33, 22, 4,
+ 22,
+ 20, 30, 7, 54, 13, 19, 48, 32, 13, 38, 9, 4, 22, 26, 22, 43, 5, 47, 14, 15, 21, 15, 48,
+ 10, 15, 47, 22, 9, 52, 4, 16, 22, 47, 9, 13, 44, 15, 5, 19, 2, 55, 36, 49, 25, 52, 21,
+ 5,
+ 19, 46, 2, 51, 45, 12, 54, 47, 47, 23, 17, 26, 52, 36, 49, 4, 42, 18, 20, 22, 47, 18,
+ 37,
+ 28, 19, 11, 21, 13, 37, 51, 2, 43, 36, 43, 0, 40, 50, 27, 40, 41, 31, 41, 53, 2, 17, 4,
+ 35, 52, 22, 25, 21, 16, 5, 41, 54, 5, 40, 3, 38, 12, 10, 53, 48, 28, 9, 7, 46, 28, 3, 9,
+ 44, 29, 39, 3, 41, 15, 29, 30, 47, 21, 12, 27, 53, 7, 34, 53, 53, 50, 53, 23, 46, 52,
+ 40,
+ 21, 3, 46, 49, 17, 14, 36, 10, 54, 51, 22, 25, 34, 49, 49, 26, 45, 45, 17, 30, 19, 6,
+ 49,
+ 41, 9, 19, 25, 51, 23, 55, 11, 0, 1, 13, 26, 15, 41, 38, 19, 51, 21, 11, 8, 55, 25, 21,
+ 15, 18, 15, 48, 4, 37, 36, 5, 45, 13, 13, 16, 26, 0, 41, 8, 51, 20, 38, 28, 46, 3, 37,
+ 52,
+ 6, 24, 11, 18, 39, 25, 48, 16, 41, 50, 44, 48, 7, 29, 14, 15, 28, 7, 46, 15, 16, 46, 20,
+ 35, 6, 27, 10, 17, 1, 42, 30, 37, 41, 37, 52, 55, 4, 6, 17, 27, 33, 45, 37, 11, 29, 16,
+ 42, 33, 39, 35, 33, 30, 25, 37, 6, 25, 22, 43, 31, 42, 25, 15, 27, 19, 15, 10, 1, 45,
+ 24,
+ 23, 17, 17, 33, 12, 53, 30, 44, 30, 2, 30, 8, 45, 49, 48, 46, 52, 13, 41, 29, 46, 39,
+ 50,
+ 51, 19, 55, 36, 29, 23, 8, 11, 49, 43, 45, 51, 2, 41, 53, 6, 38, 52, 26, 45, 0, 55, 14,
+ 42, 25, 10, 4, 39, 5, 47, 42, 55, 37, 35, 53, 14, 27, 54, 41, 19, 34, 38, 43, 22, 41,
+ 23,
+ 12, 13, 17, 36, 23, 41, 15, 34, 24, 44, 21, 3, 25, 10, 14, 43, 16, 35, 45, 1, 22, 26,
+ 20,
+ 5, 8, 37, 42, 47, 1, 2, 33, 2, 21, 8, 36, 50, 6, 45, 40, 48, 16, 12, 1, 55, 0, 53, 51,
+ 35,
+ 19, 14, 3, 21, 33, 2, 54, 33, 2, 18, 53, 34, 19, 23, 32, 27, 39, 13, 48, 27, 12, 7, 50,
+ 16, 49, 35, 27, 12, 29, 6, 34, 7, 18, 50, 6, 49, 24, 1, 18, 53, 27, 36, 0, 37, 42, 51,
+ 12,
+ 38, 8, 29, 38, 11, 24, 4, 2, 15, 19, 1, 25, 9, 30, 50, 30, 8, 15, 50, 52, 25, 8, 29, 44,
+ 7, 41, 30, 45, 9, 23, 20, 49, 15, 16, 48, 34, 10, 44, 52, 22, 4, 6, 2, 8, 23, 13, 39, 7,
+ 31, 29, 4, 35, 43, 2, 33, 34, 24, 41, 38, 47, 5, 38, 28, 34, 1, 44, 14, 13, 12, 8, 6, 0,
+ 24, 9, 4, 39, 37, 32, 18, 38, 15, 29, 14, 11, 40, 34, 12, 16, 7, 7, 50, 18, 24, 30, 15,
+ 13, 41, 42, 47, 22, 17, 14, 38, 46, 45, 22, 12, 12, 12, 25, 11, 24, 41, 8, 51, 51, 25,
+ 46,
+ 15, 13, 47, 38, 20, 0, 21, 7, 30, 49, 42, 43, 53, 24, 19, 17, 46, 50, 15, 33, 1, 42, 14,
+ 55, 26, 17, 41, 39, 23, 46, 35, 39, 16, 16, 37, 50, 38, 24, 20, 32, 51, 22, 53, 50, 10,
+ 39, 4, 2, 27, 1, 25, 18, 40, 50, 9, 35, 37, 27, 37, 39, 29, 2, 38, 32, 6, 30, 32, 4, 43,
+ 46, 21, 9, 40, 45, 49, 34, 37, 4, 55, 19, 47, 3, 42, 33, 13, 43, 3, 3, 22, 49
+ };
+ long startTime = System.currentTimeMillis();
+ System.out.println(sol.triangleNumber(test2));
+ System.out.println("Used time: " + (System.currentTimeMillis() - startTime));
+ }
+}
diff --git a/src/main/java/com/company/smartnews/onsite/TriangleNumberII.java b/src/main/java/com/company/smartnews/onsite/TriangleNumberII.java
new file mode 100644
index 0000000000..7b9579dcbd
--- /dev/null
+++ b/src/main/java/com/company/smartnews/onsite/TriangleNumberII.java
@@ -0,0 +1,156 @@
+package com.company.smartnews.onsite;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Leetcode 611. Valid Triangle Number
+ *
+ * Follow up: collect all unique triangle numbers
+ */
+public class TriangleNumberII {
+
+ public Set> triangleNumber(int[] nums) {
+ Set> results = new HashSet<>();
+ if (nums.length < 3) {
+ return results;
+ }
+ int n = nums.length;
+ Arrays.sort(nums);
+ /*
+ i 0 1 2 3
+ nums 2 2 3 4
+ c
+ b
+ a
+ ans += 2 - 0, ans = 2
+ >>>>>>>>>>>>>>>>>>>>>>
+ i 0 1 2 3
+ nums 2 2 3 4
+ c
+ b
+ a
+ ans remains 2
+ >>>>>>>>>>>>>>>>>>>>>>
+ i 0 1 2 3
+ nums 2 2 3 4
+ c
+ b
+ a
+ ans remains 2
+ >>>>>>>>>>>>>>>>>>>>>
+ i 0 1 2 3
+ nums 2 2 3 4
+ c
+ b
+ a
+ ans += 1, ans = 3
+ >>>>>>>>>>>>>>>>>>>>>
+ */
+
+ for (int c = n - 1; c > 1; c--) { // n iteration
+ int b = c - 1;
+ int a = 0;
+ while (a < b) { // n iteration
+ if (nums[a] + nums[b] > nums[c]) {
+ // ans += b - a;
+ collect(results, nums, a, b, c);
+ b--;
+ } else {
+ a++;
+ }
+ }
+ }
+ return results;
+ }
+
+ private void collect(Set> results, int[] nums, int a, int b, int c) {
+ for (int i = a; i < b; i++) {
+ List result = new ArrayList<>();
+ result.add(nums[a]);
+ result.add(nums[b]);
+ result.add(nums[c]);
+ results.add(result);
+ }
+ }
+
+ public static void main(String[] args) {
+ TriangleNumberII sol = new TriangleNumberII();
+ int[] test1 = new int[]{2, 2, 3, 4};
+ int[] test2 =
+ new int[]{
+ 15, 44, 16, 43, 47, 47, 45, 27, 46, 2, 28, 12, 49, 22, 36, 12, 6, 48, 28, 19, 18, 34,
+ 46,
+ 38, 42, 3, 21, 3, 54, 35, 21, 54, 13, 46, 50, 23, 53, 43, 5, 48, 40, 48, 10, 31, 15, 35,
+ 50, 8, 48, 55, 52, 18, 54, 16, 35, 4, 43, 55, 34, 13, 5, 13, 27, 41, 19, 22, 21, 26, 48,
+ 4, 15, 1, 45, 51, 13, 49, 22, 33, 18, 18, 52, 27, 6, 41, 7, 11, 48, 17, 37, 31, 42, 3,
+ 45,
+ 22, 6, 45, 42, 5, 28, 39, 35, 30, 24, 21, 49, 49, 47, 54, 28, 42, 40, 26, 47, 8, 28, 1,
+ 44, 4, 45, 23, 49, 53, 12, 48, 16, 27, 36, 21, 18, 41, 43, 9, 55, 27, 37, 41, 5, 43, 12,
+ 45, 0, 34, 19, 48, 14, 22, 43, 14, 13, 38, 15, 7, 41, 8, 37, 13, 45, 31, 47, 38, 45, 38,
+ 50, 44, 20, 40, 39, 38, 26, 29, 24, 10, 30, 23, 53, 38, 39, 3, 37, 4, 15, 22, 29, 4, 5,
+ 4,
+ 4, 19, 35, 30, 30, 49, 16, 32, 36, 26, 37, 53, 46, 28, 24, 13, 12, 29, 2, 36, 21, 19,
+ 15,
+ 11, 22, 10, 30, 29, 40, 14, 17, 39, 36, 17, 23, 39, 13, 29, 51, 8, 55, 10, 10, 47, 39,
+ 1,
+ 46, 27, 18, 7, 49, 38, 27, 14, 26, 35, 5, 46, 54, 12, 18, 30, 11, 6, 29, 52, 44, 38, 51,
+ 22, 26, 24, 41, 13, 39, 27, 0, 36, 38, 7, 37, 7, 9, 25, 4, 8, 52, 33, 46, 33, 42, 43,
+ 17,
+ 23, 20, 23, 41, 8, 47, 16, 48, 46, 35, 35, 24, 0, 17, 12, 40, 52, 11, 16, 7, 33, 6, 21,
+ 30, 32, 55, 52, 52, 28, 11, 35, 39, 15, 27, 47, 52, 0, 11, 41, 50, 10, 13, 10, 5, 40,
+ 21,
+ 0, 27, 12, 39, 20, 27, 39, 19, 28, 5, 51, 45, 19, 3, 1, 15, 53, 31, 45, 36, 33, 22, 4,
+ 22,
+ 20, 30, 7, 54, 13, 19, 48, 32, 13, 38, 9, 4, 22, 26, 22, 43, 5, 47, 14, 15, 21, 15, 48,
+ 10, 15, 47, 22, 9, 52, 4, 16, 22, 47, 9, 13, 44, 15, 5, 19, 2, 55, 36, 49, 25, 52, 21,
+ 5,
+ 19, 46, 2, 51, 45, 12, 54, 47, 47, 23, 17, 26, 52, 36, 49, 4, 42, 18, 20, 22, 47, 18,
+ 37,
+ 28, 19, 11, 21, 13, 37, 51, 2, 43, 36, 43, 0, 40, 50, 27, 40, 41, 31, 41, 53, 2, 17, 4,
+ 35, 52, 22, 25, 21, 16, 5, 41, 54, 5, 40, 3, 38, 12, 10, 53, 48, 28, 9, 7, 46, 28, 3, 9,
+ 44, 29, 39, 3, 41, 15, 29, 30, 47, 21, 12, 27, 53, 7, 34, 53, 53, 50, 53, 23, 46, 52,
+ 40,
+ 21, 3, 46, 49, 17, 14, 36, 10, 54, 51, 22, 25, 34, 49, 49, 26, 45, 45, 17, 30, 19, 6,
+ 49,
+ 41, 9, 19, 25, 51, 23, 55, 11, 0, 1, 13, 26, 15, 41, 38, 19, 51, 21, 11, 8, 55, 25, 21,
+ 15, 18, 15, 48, 4, 37, 36, 5, 45, 13, 13, 16, 26, 0, 41, 8, 51, 20, 38, 28, 46, 3, 37,
+ 52,
+ 6, 24, 11, 18, 39, 25, 48, 16, 41, 50, 44, 48, 7, 29, 14, 15, 28, 7, 46, 15, 16, 46, 20,
+ 35, 6, 27, 10, 17, 1, 42, 30, 37, 41, 37, 52, 55, 4, 6, 17, 27, 33, 45, 37, 11, 29, 16,
+ 42, 33, 39, 35, 33, 30, 25, 37, 6, 25, 22, 43, 31, 42, 25, 15, 27, 19, 15, 10, 1, 45,
+ 24,
+ 23, 17, 17, 33, 12, 53, 30, 44, 30, 2, 30, 8, 45, 49, 48, 46, 52, 13, 41, 29, 46, 39,
+ 50,
+ 51, 19, 55, 36, 29, 23, 8, 11, 49, 43, 45, 51, 2, 41, 53, 6, 38, 52, 26, 45, 0, 55, 14,
+ 42, 25, 10, 4, 39, 5, 47, 42, 55, 37, 35, 53, 14, 27, 54, 41, 19, 34, 38, 43, 22, 41,
+ 23,
+ 12, 13, 17, 36, 23, 41, 15, 34, 24, 44, 21, 3, 25, 10, 14, 43, 16, 35, 45, 1, 22, 26,
+ 20,
+ 5, 8, 37, 42, 47, 1, 2, 33, 2, 21, 8, 36, 50, 6, 45, 40, 48, 16, 12, 1, 55, 0, 53, 51,
+ 35,
+ 19, 14, 3, 21, 33, 2, 54, 33, 2, 18, 53, 34, 19, 23, 32, 27, 39, 13, 48, 27, 12, 7, 50,
+ 16, 49, 35, 27, 12, 29, 6, 34, 7, 18, 50, 6, 49, 24, 1, 18, 53, 27, 36, 0, 37, 42, 51,
+ 12,
+ 38, 8, 29, 38, 11, 24, 4, 2, 15, 19, 1, 25, 9, 30, 50, 30, 8, 15, 50, 52, 25, 8, 29, 44,
+ 7, 41, 30, 45, 9, 23, 20, 49, 15, 16, 48, 34, 10, 44, 52, 22, 4, 6, 2, 8, 23, 13, 39, 7,
+ 31, 29, 4, 35, 43, 2, 33, 34, 24, 41, 38, 47, 5, 38, 28, 34, 1, 44, 14, 13, 12, 8, 6, 0,
+ 24, 9, 4, 39, 37, 32, 18, 38, 15, 29, 14, 11, 40, 34, 12, 16, 7, 7, 50, 18, 24, 30, 15,
+ 13, 41, 42, 47, 22, 17, 14, 38, 46, 45, 22, 12, 12, 12, 25, 11, 24, 41, 8, 51, 51, 25,
+ 46,
+ 15, 13, 47, 38, 20, 0, 21, 7, 30, 49, 42, 43, 53, 24, 19, 17, 46, 50, 15, 33, 1, 42, 14,
+ 55, 26, 17, 41, 39, 23, 46, 35, 39, 16, 16, 37, 50, 38, 24, 20, 32, 51, 22, 53, 50, 10,
+ 39, 4, 2, 27, 1, 25, 18, 40, 50, 9, 35, 37, 27, 37, 39, 29, 2, 38, 32, 6, 30, 32, 4, 43,
+ 46, 21, 9, 40, 45, 49, 34, 37, 4, 55, 19, 47, 3, 42, 33, 13, 43, 3, 3, 22, 49
+ };
+ long startTime1 = System.currentTimeMillis();
+ System.out.println(sol.triangleNumber(test1));
+ System.out.println("Test 1 used time: " + (System.currentTimeMillis() - startTime1));
+ long startTime2 = System.currentTimeMillis();
+ System.out.println(sol.triangleNumber(test2));
+ System.out.println("Test 2 used time: " + (System.currentTimeMillis() - startTime2));
+ }
+}
diff --git a/src/main/java/com/company/smartnews/onsite/ValidStackSequence.java b/src/main/java/com/company/smartnews/onsite/ValidStackSequence.java
new file mode 100644
index 0000000000..cb49644cd7
--- /dev/null
+++ b/src/main/java/com/company/smartnews/onsite/ValidStackSequence.java
@@ -0,0 +1,69 @@
+package com.company.smartnews.onsite;
+
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+public class ValidStackSequence {
+
+ /**
+ * LeetCode 946: Valid Stack Sequence
+ *
+ * C:
+ * What is the data type of input and output? array and boolean?
+ * What if we meet a null as input?
+ * Can we assume the length of popped and pushed are the same? And how long they can be?
+ * What is the value range if the element in the sequences
+ * A:
+ * The input can be null, thus return false
+ * The length of popped and pushed sequences can be different, if popped is longer than pushed,
+ * return false
+ * No duplicate element in the sequences
+ * R:
+ * Use a stack to simulate the pushed and popped sequence.
+ *
Use a pointer popCount points at the head of popped sequence initially, the semantic of the
+ * pointer is : the left side of the pointer is the valid popped sequence we have been checked.
+ *
+ * if the pop count is equal to the length of popped sequence, the popped sequence is
+ * valid
+ * T:
+ * pushed:1,2,3, popped: 1,2,3 => true, 3,2,1=> true, 3,1,2 => false, null => false,
+ */
+ public static boolean isValidStachSequence(int[] pushed, int[] popped) {
+ if (pushed == null || popped == null || pushed.length < popped.length) {
+ return false;
+ }
+ Deque stack = new ArrayDeque<>();
+ int popCount = 0;
+ for (int i = 0; i < pushed.length; i++) {
+ stack.addLast(pushed[i]);
+ while (!stack.isEmpty() && popCount < popped.length && stack.peekLast() == popped[popCount]) {
+ stack.pollLast();
+ popCount++;
+ }
+ }
+ return popCount == popped.length;
+ }
+
+ public static void main(String[] args) {
+ int[] pushed1 = new int[]{1, 2, 3};
+ int[] pushed2 = new int[]{1, 2, 3, 4, 5, 6};
+ int[] popped1 = new int[]{1, 2, 3};
+ int[] popped2 = new int[]{3, 2, 1};
+ int[] popped3 = null;
+ int[] popped4 = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
+ int[] popped5 = new int[]{3, 1, 2};
+
+ assertTrue(isValidStachSequence(pushed1, popped1));
+ assertTrue(isValidStachSequence(pushed1, popped2));
+ assertTrue(isValidStachSequence(pushed2, popped1));
+ assertTrue(isValidStachSequence(pushed2, popped2));
+
+ assertFalse(isValidStachSequence(pushed1, popped3));
+ assertFalse(isValidStachSequence(pushed1, popped5));
+ assertFalse(isValidStachSequence(pushed1, popped4));
+
+ }
+}
diff --git a/src/main/java/com/company/yoyo/onsite/MajorityElementVariant.java b/src/main/java/com/company/yoyo/onsite/MajorityElementVariant.java
new file mode 100644
index 0000000000..b27d56d6d5
--- /dev/null
+++ b/src/main/java/com/company/yoyo/onsite/MajorityElementVariant.java
@@ -0,0 +1,171 @@
+package com.company.yoyo.onsite;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class MajorityElementVariant {
+
+ /**
+ * Leetcode 229. Majority Element II Variant Given an sorted integer array of size n, find all
+ * elements that appear more than ⌊ n/3 ⌋ times.
+ *
+ * Note: The algorithm should run in linear time and in O(1) space.
+ *
+ *
Example 1:
+ *
+ *
Input: [1, 3, 3] Output: [3]
+ *
+ *
Example 2:
+ *
+ *
Input: [1, 2, 2, 3, 6, 6, 6, 7] Output: [6]
+ */
+ public static void main(String[] args) {
+ int[] test1 = new int[] {1, 2, 2, 3, 6, 6, 6, 7};
+ int[] test2 = new int[] {1};
+ int[] test3 = new int[] {1, 2};
+ int[] test4 = new int[] {1, 2, 3};
+ // There are more than 33 integer '30's in the test 5 array, the length of test 5 is 100
+ int[] test5 =
+ new int[] {
+ 2, 3, 4, 4, 5, 5, 9, 11, 11, 14, 14, 15, 18, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 56, 57, 58, 62, 62, 62, 63, 65, 67, 67, 68, 70, 71, 71, 71, 71, 72, 72, 74, 75,
+ 75, 76, 76, 78, 78, 79, 79, 79, 79, 81, 82, 83, 83, 84, 84, 86, 87, 88, 90, 91, 92, 94,
+ 94, 95, 95, 97, 97, 98, 99, 99, 100, 100
+ };
+ List tests = new ArrayList<>();
+ tests.add(test1);
+ tests.add(test2);
+ tests.add(test3);
+ tests.add(test4);
+ tests.add(test5);
+
+ int i = 1;
+ for (int[] testCase : tests) {
+ List myResult = myMajorityElement(testCase);
+ List expected = majorityElement(testCase);
+ Collections.sort(expected);
+ System.out.println("test " + i + " My Result: " + myResult.toString());
+ System.out.println("test " + i + " Expected: " + expected.toString());
+ i++;
+ assertEquals(expected, myResult);
+ }
+ }
+
+ public static List majorityElement(int[] nums) {
+ List result = new ArrayList<>();
+ if (nums == null || nums.length == 0) {
+ return result;
+ }
+ // At maximum we can have two elments qualified the condition
+ int count1 = 0;
+ int count2 = 0;
+ int candidate1 = 0;
+ int candidate2 = 1;
+ for (int num : nums) {
+ // System.out.println(candidate1 + " : " + count1);
+ // System.out.println(candidate2 + " : " + count2);
+ if (num == candidate1) {
+ count1++;
+ } else if (num == candidate2) {
+ count2++;
+ } else if (count1 == 0) {
+ candidate1 = num;
+ count1 = 1;
+ } else if (count2 == 0) {
+ candidate2 = num;
+ count2 = 1;
+ } else {
+ count1--;
+ count2--;
+ }
+ }
+ // System.out.println(candidate1 + " : " + count1);
+ // System.out.println(candidate2 + " : " + count2);
+ count1 = 0;
+ count2 = 0;
+ for (int num : nums) {
+ if (num == candidate1) {
+ count1++;
+ } else if (num == candidate2) {
+ count2++;
+ }
+ }
+ if (count1 > nums.length / 3) {
+ result.add(candidate1);
+ }
+ if (count2 > nums.length / 3) {
+ result.add(candidate2);
+ }
+ return result;
+ }
+
+ public static List myMajorityElement(int[] nums) {
+ Set res = new HashSet<>();
+
+ if (nums == null || nums.length == 0) {
+ return new ArrayList<>();
+ } else if (nums.length < 3) {
+ List shortRes = new ArrayList<>(2);
+ for (int num : nums) {
+ shortRes.add(num);
+ }
+ return shortRes;
+ }
+
+ // Arrays.sort(nums);
+ int len = nums.length;
+ for (int pivot = len / 3; pivot < len; pivot += len / 3) {
+ int target = nums[pivot];
+ int left = pivot - len / 3;
+ int first = findFirst(target, nums, left, pivot);
+ int right = (pivot + len / 3 > len - 1) ? len - 1 : pivot + len / 3;
+ int last = findLast(target, nums, pivot, right);
+ if (last - first + 1 > len / 3) {
+ res.add(target);
+ }
+ }
+ return new ArrayList<>(res);
+ }
+
+ private static int findLast(int T, int[] nums, int pivot, int right) {
+ int l = pivot;
+ int r = right;
+ while (l + 1 < r) {
+ int mid = l + (r - l) / 2;
+ if (nums[mid] == T) {
+ l = mid;
+ } else if (nums[mid] > T) {
+ r = mid;
+ }
+ }
+ if (nums[r] == T) {
+ return r;
+ } else {
+ return l;
+ }
+ }
+
+ private static int findFirst(int T, int[] nums, int left, int pivot) {
+ int l = left;
+ int r = pivot;
+ while (l + 1 < r) {
+ int mid = l + (r - l) / 2;
+ if (nums[mid] == T) {
+ r = mid;
+ } else if (nums[mid] < T) {
+ l = mid;
+ }
+ }
+ if (nums[l] == T) {
+ return l;
+ } else {
+ return r;
+ }
+ }
+}
From 496cbf6ae9c8302c1958b2bcd9fd9f19c46a93bc Mon Sep 17 00:00:00 2001
From: Edward Tang <3278807+EdwardTang@users.noreply.github.com>
Date: Fri, 13 Mar 2020 00:09:10 -0700
Subject: [PATCH 6/6] C3ai (#5)
* c3ai add c3ai phone interview question
* autonomic phone interview
Co-authored-by: Yongbing Tang
---
.../autonomic/phone/MaxDistinctElements.java | 79 ++++++++++++++++
.../com/company/c3ai/phone/CounterVirus.java | 64 +++++++++++++
.../company/servicenow/phone/SliceMatrix.java | 75 +++++++++++++++
.../dfs/StringPermutationWithDupChars.java | 34 +++++++
src/main/java/com/laioffer/dfs/_99Cents.java | 93 +++++++++++++++++++
5 files changed, 345 insertions(+)
create mode 100644 src/main/java/com/company/autonomic/phone/MaxDistinctElements.java
create mode 100644 src/main/java/com/company/c3ai/phone/CounterVirus.java
create mode 100644 src/main/java/com/company/servicenow/phone/SliceMatrix.java
create mode 100644 src/main/java/com/laioffer/dfs/StringPermutationWithDupChars.java
create mode 100644 src/main/java/com/laioffer/dfs/_99Cents.java
diff --git a/src/main/java/com/company/autonomic/phone/MaxDistinctElements.java b/src/main/java/com/company/autonomic/phone/MaxDistinctElements.java
new file mode 100644
index 0000000000..2fe4da2f97
--- /dev/null
+++ b/src/main/java/com/company/autonomic/phone/MaxDistinctElements.java
@@ -0,0 +1,79 @@
+package com.company.autonomic.phone;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.PriorityQueue;
+
+public class MaxDistinctElements {
+
+ /**
+ * Maximum distinct elements after removing k elements
+ *
+ * Given an array arr[] containing n elements. The problem is to find maximum number of
+ * distinct elements (non-repeating) after removing k elements from the array. Note: 1 <= k <= n.
+ *
+ *
Examples:
+ *
+ *
Input : arr[] = {5, 7, 5, 5, 1, 2, 2}, k = 3 Output : 4 Remove 2 occurrences of element 5
+ * and 1 occurrence of element 2.
+ *
+ *
Input : arr[] = {1, 2, 3, 4, 5, 6, 7}, k = 5 Output : 2
+ *
+ *
Input : arr[] = {1, 2, 2, 2}, k = 1 Output : 1
+ *
+ *
Approach: Following are the steps:
+ *
+ *
Create a hash table to store the frequency of each element. Insert frequency of each element
+ * in a max heap. Now, perform the following operation k times. Remove an element from the max
+ * heap. Decrement its value by 1. After this if element is not equal to 0, then again push the
+ * element in the max heap. After the completion of step 3, the number of elements in the max heap
+ * is the required answer.
+ *
+ *
High level: Reducing the most frequent elements to get max distinct element number. Mid
+ * -level: Insert the frequencies of each, do K times of reducing the frequency on the top of the
+ * max heap.
+ */
+ public static int maxDistinctElementNumber(int[] input, int k) {
+ Map freqMap = new HashMap<>();
+ PriorityQueue maxHeap = new PriorityQueue<>(Collections.reverseOrder());
+
+ // Init the frequency map
+ for (int num : input) {
+ Integer freq = freqMap.get(num);
+ if (freq == null) {
+ freq = 0;
+ }
+ freq++;
+ freqMap.put(num, freq);
+ }
+
+ for (Map.Entry e : freqMap.entrySet()) {
+ maxHeap.offer(e.getValue());
+ }
+
+ for (int i = k; i > 0; i--) {
+ Integer freq = maxHeap.poll();
+ freq--;
+ if (freq > 0) {
+ maxHeap.offer(freq);
+ }
+ }
+ return maxHeap.size();
+ }
+
+ public static void main(String[] args) {
+ int[] arr1 = {5, 7, 5, 5, 1, 2, 2};
+ int k1 = 3;
+ int[] arr2 = {1, 2, 3, 4, 5, 6, 7};
+ int k2 = 5;
+ int[] arr3 = {1, 2, 2, 2};
+ int k3 = 1;
+ System.out.println(
+ "For arr1 and k1 Maximum distinct elements = " + maxDistinctElementNumber(arr1, k1));
+ System.out.println(
+ "For arr2 and k2 Maximum distinct elements = " + maxDistinctElementNumber(arr2, k2));
+ System.out.println(
+ "For arr3 and k3 Maximum distinct elements = " + maxDistinctElementNumber(arr3, k3));
+ }
+}
diff --git a/src/main/java/com/company/c3ai/phone/CounterVirus.java b/src/main/java/com/company/c3ai/phone/CounterVirus.java
new file mode 100644
index 0000000000..5f2d0615a4
--- /dev/null
+++ b/src/main/java/com/company/c3ai/phone/CounterVirus.java
@@ -0,0 +1,64 @@
+package com.company.c3ai.phone;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class CounterVirus {
+
+ public static void main(String[] args) {
+ int[] tcpPacket = new int[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ System.out.println(Arrays.toString(tcpPacket));
+ iAmVirus(tcpPacket);
+ System.out.println(Arrays.toString(tcpPacket));
+ findComplementIndex(tcpPacket).forEach(i -> System.out.print(i + " "));
+ System.out.println();
+ changeMeBack(tcpPacket);
+ System.out.println(Arrays.toString(tcpPacket));
+ }
+
+ private static void iAmVirus(int[] tcpPacket) {
+ int n = tcpPacket.length;
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < n; j++) {
+ if ((i + 1) * (j + 1) <= n) {
+ tcpPacket[(i + 1) * (j + 1) - 1] = complement(tcpPacket[(i + 1) * (j + 1) - 1]);
+ // System.out.print(Arrays.toString(tcpPacket));
+ // System.out.print(" ");
+ // System.out.println((i + 1) * (j + 1));
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ private static int complement(int i) {
+ return i == 0 ? 1 : 0;
+ }
+
+ private static List findComplementIndex(int[] tcpPacket) {
+ List res = new ArrayList<>();
+ for (int i = 0; i < tcpPacket.length; i++) {
+ if (tcpPacket[i] == 1) {
+ res.add(i);
+ }
+ }
+ return res;
+ }
+
+ /**
+ * Complement the digit at 0,3,8,15,24.....
+ * @param tcpPacket given tcp packet
+ */
+ private static void changeMeBack(int[] tcpPacket) {
+ // write your code here
+ int index = 0;
+ int i = 1;
+ while (index < tcpPacket.length) {
+ tcpPacket[index] = complement(tcpPacket[index]);
+ index += i * 2 + 1;
+ i++;
+ }
+ }
+}
diff --git a/src/main/java/com/company/servicenow/phone/SliceMatrix.java b/src/main/java/com/company/servicenow/phone/SliceMatrix.java
new file mode 100644
index 0000000000..ec6d852a43
--- /dev/null
+++ b/src/main/java/com/company/servicenow/phone/SliceMatrix.java
@@ -0,0 +1,75 @@
+package com.company.servicenow.phone;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class SliceMatrix {
+
+ /**
+ * Write a function to slice the matrix with given row numbers and given columns numbers
+ */
+ public static void main(String[] args) {
+ int[][] test =
+ new int[][] {
+ new int[] {1, 1, 1, 1},
+ new int[] {0, 0, 0, 0},
+ new int[] {2, 1, 3, 3},
+ new int[] {1, 2, 4, 4}
+ };
+ int[] rows = new int[] {0, 1};
+ int[] cols = new int[] {1, 2};
+ // rows
+ // 0 [1 1 1 1
+ // 1 0 0 0 0
+ // 2 1 3 3 ==> [2 3
+ // 1 2 4 4] 1 4]
+ // cols 1 2
+ int[][] result = findSlicedMatrix(test, rows, cols);
+ for (int[] r : result) {
+ for (int num : r) {
+ System.out.print(num + " ");
+ }
+ System.out.println();
+ }
+ }
+
+ /**
+ * Assumption: M, rows, cols are not null nor empty.
+ * High level: use set to check if current row or column should be skipped. Use pointer to create new result 2D-array
+ * Time: (N*M), Space(rows.length + cols.length)
+ */
+ public static int[][] findSlicedMatrix(int[][] M, int[] rows, int[] cols) {
+ // todo: validate input
+ int totalRows = M.length;
+ int totalCols = M[0].length;
+ int remainRows = totalRows - rows.length;
+ int remainCols = totalCols - cols.length;
+ int[][] res = new int[remainRows][remainCols];
+
+ // find the remaining row index and col index in rows and cols,
+ Set slicedRows = new HashSet<>();
+ Set slicedCols = new HashSet<>();
+
+ for (int row : rows) {
+ slicedRows.add(row);
+ }
+ for (int col : cols) {
+ slicedCols.add(col);
+ }
+
+ for (int i = 0, curRow = 0; i < totalRows; i++) {
+ if (!slicedRows.contains(i)) {
+ for (int j = 0, curCol = 0; j < totalCols; j++) {
+ if (!slicedCols.contains(j)) {
+ if (curRow < remainRows && curCol < remainCols) {
+ res[curRow][curCol] = M[i][j];
+ }
+ curCol++;
+ }
+ }
+ curRow++;
+ }
+ }
+ return res;
+ }
+}
diff --git a/src/main/java/com/laioffer/dfs/StringPermutationWithDupChars.java b/src/main/java/com/laioffer/dfs/StringPermutationWithDupChars.java
new file mode 100644
index 0000000000..bb8adc0483
--- /dev/null
+++ b/src/main/java/com/laioffer/dfs/StringPermutationWithDupChars.java
@@ -0,0 +1,34 @@
+package com.laioffer.dfs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+Assumption: (1) given input is char array ahd not null, not empty (2) output is a list of all permutation Strings
+High level: use DFS to traverse all permutations. (1) N levels of recursion tree, each level represents one position. (2) at each level, we need traverse each node with remaining unused letters: i-th level, each node: (n - i) branches
+Recursion tree:
+ root = aab
+ / | \
+ i = 0, 1, 2 swap(0,0). swap(0,1) swap(0, 2)
+position 0 **a**ab ~~**a**ab~~ **b**aa n = 3
+ / \ / \ / \
+ i = 1, 2 swap(1,1) swap(1,2) swap(1,1) swap(1,2)
+position 1 a**a**b a**b**a ~~a**a**b a**b**a~~ b**a**a. ~~b**a**a~~ * (3-1)
+ | | | | | |
+ i = 2 swap(2,2) swap(2,2)
+ position 2 aa**b** ab**a** ~~aa**b** ab**a**~~ ba**a** ~~ba**a**~~ * (3 - 2)
+ clone each string at position 2: O(n) * O(n!) brances
+Time: O(N!*N), Space(the height of the recursion tree) = O(N)
+*/
+public class StringPermutationWithDupChars {
+ public static List findPermutations(char[] input) {
+ List result = new ArrayList<>();
+ dfs(input, 0, result);
+ return result;
+ }
+
+ public static void dfs(char[] input, int index, List result) {
+
+ }
+}
+
diff --git a/src/main/java/com/laioffer/dfs/_99Cents.java b/src/main/java/com/laioffer/dfs/_99Cents.java
new file mode 100644
index 0000000000..59180aaa23
--- /dev/null
+++ b/src/main/java/com/laioffer/dfs/_99Cents.java
@@ -0,0 +1,93 @@
+package com.laioffer.dfs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class _99Cents {
+
+ /**
+ * Given a number of different denominations of coins (e.g., 1 cent, 5 cents, 10 cents, 25 cents),
+ * get all the possible ways to pay a target number of cents.
+ *
+ * Arguments
+ *
+ *
coins - an array of positive integers representing the different denominations of coins,
+ * there are no duplicate numbers and the numbers are sorted by descending order, eg. {25, 10, 5,
+ * 2, 1} target - a non-negative integer representing the target number of cents, eg. 99
+ * Assumptions
+ *
+ *
coins is not null and is not empty, all the numbers in coins are positive target >= 0 You
+ * have infinite number of coins for each of the denominations, you can pick any number of the
+ * coins. Return
+ *
+ *
a list of ways of combinations of coins to sum up to be target. each way of combinations is
+ * represented by list of integer, the number at each index means the number of coins used for the
+ * denomination at corresponding index. Examples
+ *
+ *
coins = {2, 1}, target = 4, the return should be
+ *
+ *
[
+ *
+ *
[0, 4], (4 cents can be conducted by 0 * 2 cents + 4 * 1 cents)
+ *
+ *
[1, 2], (4 cents can be conducted by 1 * 2 cents + 2 * 1 cents)
+ *
+ *
[2, 0] (4 cents can be conducted by 2 * 2 cents + 0 * 1 cents)
+ *
+ *
]
+ */
+ public static void main(String[] args) {
+ int[] coin = new int[] {25, 10, 5, 1};
+ findCoinCombination(coin, 99, 0, new int[4]);
+ List> result = combinations(99, coin);
+ }
+
+ public static List> combinations(int target, int[] coins) {
+ List> result = new ArrayList>();
+ List cur = new ArrayList();
+ helper(target, coins, 0, cur, result);
+ return result;
+ }
+
+ private static void helper(
+ int target, int[] coins, int index, List cur, List> result) {
+ if (index == coins.length - 1) {
+ if (target % coins[coins.length - 1] == 0) {
+ cur.add(target / coins[coins.length - 1]);
+ result.add(new ArrayList(cur));
+ cur.remove(cur.size() - 1);
+ }
+ return;
+ }
+ int max = target / coins[index];
+ for (int i = 0; i <= max; i++) {
+ cur.add(i);
+ helper(target - i * coins[index], coins, index + 1, cur, result);
+ cur.remove(cur.size() - 1);
+ }
+ }
+
+ public static void findCoinCombination(int[] coin, int moneyLeft, int index, int[] sol) {
+ if (index == 3) {
+ sol[index] = moneyLeft;
+ printSol(sol, coin);
+ return;
+ }
+
+ for (int i = 0; i <= moneyLeft / coin[index]; i++) {
+ sol[index] = i;
+ findCoinCombination(coin, moneyLeft - i * coin[index], index + 1, sol);
+ }
+ }
+
+ private static void printSol(int[] sol, int[] coin) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < sol.length; i++) {
+ sb.append(sol[i]);
+ sb.append('x');
+ sb.append(coin[i]);
+ sb.append(" cent ");
+ }
+ System.out.println(sb.toString());
+ }
+}