Sei sulla pagina 1di 96

LeetCode

1. Find Minimum in Rotated Sorted Array


public class Solution {
public int findMin(int[] num) {
if (num == null) {
throw new NullPointerException();
} else if (num.length == 0) {
throw new IllegalArgumentException();
}

if (num[0] <= num[num.length - 1]) {


return num[0];
}
int min = 0;
int max = num.length -1;

while (min < max) {


int test = (min + max) / 2;

if (num[test] >= num[0]) {


min = test + 1;
} else {
max = test;
}
}
return num[min];
}
}

2. Find the contiguous subarray within an array (containing at least one number)
which has the largest product.
For example, given the array [2,3,-2,4],
the contiguous subarray [2,3] has the largest product = 6.
public class Solution {
public int maxProduct(int[] A) {
if (A == null) {
throw new NullPointerException();
} else if (A.length == 0) {
throw new IllegalArgumentException();
}
int ret = A[0];
int negCurr = A[0] < 0 ? A[0] : 0;
int posCurr = A[0] > 0 ? A[0]: 0;
for (int i = 1; i < A.length; i++) {
if (A[i] == 0) {
negCurr = 0;
posCurr = 0;
} else if (A[i] > 0) {
negCurr = negCurr * A[i];
posCurr = Math.max(A[i], posCurr * A[i]);
} else {
int tempNegCurr = negCurr;
negCurr = Math.min(A[i], posCurr * A[i]);
posCurr = tempNegCurr * A[i];
}
ret = Math.max(ret, posCurr);
}
return ret;
}
}
3. Given an input string, reverse the string word by word.
For example,
Given s = "the sky is blue",
return "blue is sky the".
click to show clarification.
Clarification:
What constitutes a word?
A sequence of non-space characters constitutes a word.
Could the input string contain leading or trailing spaces?
Yes. However, your reversed string should not contain leading or trailing spaces
.
How about multiple spaces between two words?
Reduce them to a single space in the reversed string.

public class Solution {


private int countExtraSpace(String s) {
int extra = 0;
for (int i = 1; i < s.length(); i++) {
if (Character.isSpace(s.charAt(i)) && Character.isSpace(s.charAt(i-1
))) {
extra++;
}
}
return extra;
}
// s.length() > 0 and A is exactly the right length
private void copyBarExtraSpace(String s, char[] A) {
A[0] = s.charAt(0);
int target = 1;
for (int i = 1; i < s.length(); i++) {
if (!Character.isSpace(s.charAt(i)) || !Character.isSpace(s.charAt(i
-1))) {
A[target++] = s.charAt(i);
}
}
}
private void reverse(char[] s, int start, int end) {
while (start < end) {
char temp = s[start];
s[start] = s[end];
s[end] = temp;
start++;
end--;
}
}
public String reverseWords(String s) {
if (s == null) {
throw new NullPointerException();
}
s = s.trim();
if (s.length() == 0) {
return s;
}
int numExtraSpaces = countExtraSpace(s);
char[] ret = new char[s.length() - numExtraSpaces];
copyBarExtraSpace(s, ret);
reverse(ret, 0, ret.length - 1);
int wordStart = 0;
int i = 1;
while (i < ret.length) {
if (Character.isSpace(ret[i])) {

reverse(ret, wordStart, i - 1);


wordStart = i + 1;
}
i++;
}
reverse(ret, wordStart, ret.length - 1);
return new String(ret);
}
}
Another Solution
String[] words = sentence.split(" ");
String[] reversedWords = ArrayUtils.reverse(words);
String reversedSentence = StringUtils.join(reversedWords, " ");
One more Solution
string[] words = "This is interview question".split(" ");
string rev = "";
for(int i = words.length - 1; i >= 0 ; i--)
{
rev += words[i] + " ";
}
// rev = "question interview is This "
// can also use StringBuilder:
StringBuilder revb = new StringBuilder;
for(int i = words.length - 1; i >= 0 ; i--)
{
revb.Append(words[i]);
revb.Append(" ");
}
// revb.toString() = "question interview is This "

theres one more Solution


String[] parts = "Word boundary is better than space".split("\\b");
StringBuilder sb = new StringBuilder();
for (int i = parts.length; i --> 0 ;) {
sb.append(parts[i]);
}
System.out.println("[" + sb.toString() + "]");
// prints "[space than better is boundary Word]"

OR

Recursive
public static String reverse(String s) {

int k = s.indexOf(" ");


return k == -1 ? s : reverse(s.substring(k + 1)) + " " + s.substring(0, k);
}
System.out.println("[" + reverse("This is interview question") + "]");
// prints "[question interview is This]"
4. Evaluate the value of an arithmetic expression in Reverse Polish Notation.
Valid operators are +, -, *, /. Each operand may be an integer or another expres
sion.
Some examples:
["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9
["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6
public class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<Integer>();
for (String s : tokens) {
if (s.equals("+")) {
stack.push(stack.pop() + stack.pop());
} else if (s.equals("-")) {
stack.push(-stack.pop() + stack.pop());
} else if (s.equals("*")) {
stack.push(stack.pop() * stack.pop());
} else if (s.equals("/")) {
int divisor = stack.pop();
int dividend = stack.pop();
stack.push(dividend / divisor);
} else {
stack.push(Integer.parseInt(s));
}
}
return stack.pop();
}
}

5. Given n points on a 2D plane, find the maximum number of points that lie on t
he same straight line.

Solution

/**
* Definition for a point.
* class Point {

*
int x;
*
int y;
*
Point() { x = 0; y = 0; }
*
Point(int a, int b) { x = a; y = b; }
* }
*/
class Pair {
int num;
int den;
Pair(int a, int b) {
num = a;
den = b;
}
public boolean equals(Object p2) {
Pair p = (Pair) p2;
return this.num == p.num && this.den == p.den;
}
public int hashCode() {
return num ^ den;
}
}
public class Solution {
private int GCD(int a, int b) {
if(b==0) return a;
else return GCD(b, a%b);
}
// order n^2:
// for each point, calculate slope of line to all other points, count max wi
th same slope
public int maxPoints(Point[] points) {
if (points == null) {
throw new NullPointerException();
} else if (points.length == 0) {
return 0;
}
int globalMax = 1;
for (int currentPoint = 0; currentPoint + globalMax < points.length; cur
rentPoint++) {
Point p1 = points[currentPoint];
int numVertical = 0;
int numSame = 0;
Map<Pair, Integer> slopeCounts = new HashMap<Pair, Integer>();
for (int secondPoint = currentPoint + 1; secondPoint < points.length
; secondPoint++) {
Point p2 = points[secondPoint];
// test for same point
if (p1.x == p2.x && p1.y == p2.y) {
numSame++;
}

// test for vertical


else if (p1.x == p2.x) {
numVertical++;
}
// all others have slope
else {
int num = p2.y - p1.y;
int den = p2.x - p1.x;
int gcd = GCD(num, den);
num /= gcd;
den /= gcd;
Pair p = new Pair(num, den);
slopeCounts.put(p, slopeCounts.containsKey(p) ? slopeCounts.
get(p) + 1 : 1);
}
}
int localMax = numVertical + numSame + 1;
for (Pair p : slopeCounts.keySet()) {
localMax = Math.max(localMax, slopeCounts.get(p) + numSame + 1);
}
globalMax = Math.max(globalMax, localMax);
}
return globalMax;
}
}

6. Sort a linked list in O(n log n) time using constant space complexity.

/**
* Definition for singly-linked list.
* class ListNode {
*
int val;
*
ListNode next;
*
ListNode(int x) {
*
val = x;
*
next = null;
*
}
* }
*/
public class Solution {
private ListNode splitList(ListNode head) {
ListNode slow = head;
ListNode fast = head.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;

}
ListNode secondHead = slow.next;
slow.next = null;
return secondHead;
}
private ListNode merge(ListNode head, ListNode secondHead) {
ListNode sentinel = new ListNode(0);
ListNode tail = sentinel;
while (head != null && secondHead != null) {
if (head.val < secondHead.val) {
tail.next = head;
head = head.next;
tail = tail.next;
} else {
tail.next = secondHead;
secondHead = secondHead.next;
tail = tail.next;
}
}
tail.next = head == null ? secondHead : head;
return sentinel.next;
}
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode secondHead = splitList(head);
head = sortList(head);
secondHead = sortList(secondHead);
return merge(head, secondHead);
}
}

7. Sort a linked list using insertion sort.


Solution :
/**
* Definition for singly-linked list.
* public class ListNode {
*
int val;
*
ListNode next;
*
ListNode(int x) {
*
val = x;
*
next = null;
*
}
* }
*/

// we need to have fist X nodes sorted


// then we look at the (X+1)st node and move it into place in the sorted list
public class Solution {
public ListNode insertionSortList(ListNode head) {
if (head == null) {
return null;
}
ListNode sentinel = new ListNode(0);
sentinel.next = head;
ListNode lastSorted = head;
ListNode nextToSort = head.next;
while (nextToSort != null) {
// special case if it already is where it belongs
if (nextToSort.val >= lastSorted.val) {
lastSorted = nextToSort;
nextToSort = nextToSort.next;
continue;
}
// splice node out of list
ListNode node = nextToSort;
nextToSort = nextToSort.next;
lastSorted.next = nextToSort;
// figure out where node goes in the list
// node will go after curr
ListNode curr = sentinel;
while (node.val > curr.next.val) {
curr = curr.next;
}
// put node in the list
node.next = curr.next;
curr.next = node;
}
return sentinel.next;
}
}

8. Design and implement a data structure for Least Recently Used (LRU) cache.
It should support the following operations: get and set.
get(key) - Get the value (will always be positive) of the key if the key exists
in the cache, otherwise return -1.
set(key, value) - Set or insert the value if the key is not already present. Whe
n the cache reached its capacity,
it should invalidate the least recently used item before inserting a new item.

class Node {
int key;
int value;
Node next;
Node prev;
Node() {}
Node (int key, int value) {
this.key = key;
this.value = value;
}
void delete() {
this.prev.next = this.next;
if (this.next != null) {
this.next.prev = this.prev;
}
}
void insertAfter(Node other) {
this.next = other.next;
if (this.next != null) {
this.next.prev = this;
}
this.prev = other;
other.next = this;
}
}
public class LRUCache {
int capacity;
Node head = new Node();
Node tail = head;
Map<Integer, Node> map;
public LRUCache(int capacity) {
if (capacity < 1) {
throw new IllegalArgumentException();
}
this.capacity = capacity;
this.map = new HashMap<Integer, Node>();
}
public int get(int key) {
if (map.containsKey(key)) {
Node node = map.get(key);
moveToTail(node);
return node.value;
} else {
return -1;
}
}
public void set(int key, int value) {
if (map.containsKey(key)) {

Node node = map.get(key);


moveToTail(node);
node.value = value;
} else {
if (map.size() == capacity) {
Node removing = head.next;
map.remove(removing.key);
removing.delete();
}
Node newNode = new Node(key, value);
addToTail(newNode);
map.put(key, newNode);
}
}
private void moveToTail(Node n) {
if (tail != n) {
n.delete();
addToTail(n);
}
}
private void addToTail(Node n) {
n.insertAfter(tail);
this.tail = n;
}
}

9.
Given a binary tree, return the postorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3},
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
if (root == null) {
return ret;
}
ret.addAll(postorderTraversal(root.left));
ret.addAll(postorderTraversal(root.right));
ret.add(root.val);

return ret;
}
}

10. Given a binary tree, return the preorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3},
1
\
2
/
3
return [1,2,3].
Solution :
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
if (root == null) {
return ret;
}
ret.add(root.val);
ret.addAll(preorderTraversal(root.left));
ret.addAll(preorderTraversal(root.right));
return ret;
}
}
11. Given a singly linked list L: L0 L1 Ln-1
reorder it to: L0 Ln L1 Ln-1 L2 Ln-2

Ln,

You must do this in-place without altering the nodes' values.


For example,
Given {1,2,3,4}, reorder it to {1,4,2,3}.

/**
* Definition for singly-linked list.
* class ListNode {
*
int val;

*
ListNode next;
*
ListNode(int x) {
*
val = x;
*
next = null;
*
}
* }
*/
public class Solution {
public void reorderList(ListNode head) {
Queue<ListNode> queue = new LinkedList<ListNode>();
Stack<ListNode> stack = new Stack<ListNode>();
for (ListNode current = head; current != null; current = current.next) {
queue.add(current);
stack.push(current);
}
int nodesLinked = 0;
int totalNodes = stack.size();
ListNode sentinel = new ListNode(0);
ListNode tail = sentinel;
while (nodesLinked < totalNodes - 1) {
tail.next = queue.poll();
tail = tail.next;
tail.next = stack.pop();
tail = tail.next;
nodesLinked += 2;
}
if (nodesLinked < totalNodes) {
tail.next = queue.poll();
tail = tail.next;
}
tail.next = null;
}
}
12. Given a linked list, return the node where the cycle begins. If there is no
cycle, return null.
Follow up:
Can you solve it without using extra space?
/**
* Definition for singly-linked list.
* class ListNode {
*
int val;
*
ListNode next;
*
ListNode(int x) {
*
val = x;
*
next = null;
*
}
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {

ListNode slow = head;


ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
break;
}
}
if (fast == null || fast.next == null) {
return null;
}
while (head != slow) {
head = head.next;
slow = slow.next;
}
return slow;
}
}
13. Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
/**
* Definition for singly-linked list.
* class ListNode {
*
int val;
*
ListNode next;
*
ListNode(int x) {
*
val = x;
*
next = null;
*
}
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
return true;
}
}
return false;
}
}

14. Given a string s and a dictionary of words dict, add spaces in s to construc
t a sentence where each word is a valid dictionary word.
Return all such possible sentences.
For example, given
s = "catsanddog",
dict = ["cat", "cats", "and", "sand", "dog"].
A solution is ["cats and dog", "cat sand dog"].
public class Solution {
private void wordBreakHelper(String s, int index, Set<String> dict, List<Lis
t<List<String>>> subproblems, boolean[] alreadyTried) {
if (alreadyTried[index]) {
return;
}
List<List<String>> solutions = subproblems.get(index);
// try matching entire rest of string
if (dict.contains(s.substring(index))) {
List<String> sol = new ArrayList<String>();
sol.add(s.substring(index));
solutions.add(sol);
}
// try matching from every length from 1 to s.length() - index - 1
for (int len = 1; len <= s.length() - index - 1; len++) {
if (dict.contains(s.substring(index, index + len))) {
wordBreakHelper(s, index + len, dict, subproblems, alreadyTried)
;
List<List<String>> smallSolutions = subproblems.get(index + len)
;
for (List<String> smallSol : smallSolutions) {
List<String> bigSol = new ArrayList<String>();
bigSol.add(s.substring(index, index + len));
bigSol.addAll(smallSol);
solutions.add(bigSol);
}
}
}
alreadyTried[index] = true;
}
public List<String> wordBreak(String s, Set<String> dict) {
if (s == null || dict == null) {
throw new NullPointerException();
}
if (s.length() == 0) {
return new ArrayList<String>();
}
List<List<List<String>>> subproblems = new ArrayList<List<List<String>>>

();
for (int i = 0; i < s.length(); i++) {
subproblems.add(new ArrayList<List<String>>());
}
boolean[] alreadyTried = new boolean[s.length()];
wordBreakHelper(s, 0, dict, subproblems, alreadyTried);
// generate ret
List<List<String>> fullSolutions = subproblems.get(0);
List<String> ret = new ArrayList<String>();
for (List<String> sol1 : fullSolutions) {
StringBuffer sol2 = new StringBuffer();
sol2.append(sol1.get(0));
for (int i = 1; i < sol1.size(); i++) {
sol2.append(" ");
sol2.append(sol1.get(i));
}
ret.add(sol2.toString());
}
return ret;
}
}

15. Given a string s and a dictionary of words dict, determine if s can be segme
nted into a space-separated sequence of one or more dictionary words.
For example, given
s = "leetcode",
dict = ["leet", "code"].
Return true because "leetcode" can be segmented as "leet code".
public class Solution {
private boolean wordBreakHelper(String s, int index, Set<String> dict, boole
an[] alreadyTried) {
if (alreadyTried[index]) {
return false;
}
// try matching entire rest of string
if (dict.contains(s.substring(index))) {
return true;
}
// try matching from every length from 1 to s.length() - index - 1
for (int len = 1; len <= s.length() - index - 1; len++) {
if (dict.contains(s.substring(index, index + len))) {
if (wordBreakHelper(s, index + len, dict, alreadyTried)) {
return true;
}
}
}

alreadyTried[index] = true;
return false;
}
public boolean wordBreak(String s, Set<String> dict) {
if (s == null || dict == null) {
throw new NullPointerException();
}
if (s.length() == 0) {
return true;
}
boolean[] alreadyTried = new boolean[s.length()];
return wordBreakHelper(s, 0, dict, alreadyTried);
}
}
16. A linked list is given such that each node contains an additional random poi
nter which could point to any node in the list or null.
Return a deep copy of the list.
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
*
int label;
*
RandomListNode next, random;
*
RandomListNode(int x) { this.label = x; }
* };
*/
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
if (head == null) {
return null;
}
Map<Integer, RandomListNode> cloned = new HashMap<>();
for (RandomListNode current = head; current != null; current = current.n
ext) {
RandomListNode clone = new RandomListNode(current.label);
cloned.put(current.label, clone);
}
for (RandomListNode current = head; current != null; current = current.n
ext) {
RandomListNode clone = cloned.get(current.label);
if (current.next != null) {
clone.next = cloned.get(current.next.label);
}
if (current.random != null) {
clone.random = cloned.get(current.random.label);
}
}

return cloned.get(head.label);
}
}
17. Given an array of integers, every element appears three times except for one
. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it w
ithout using extra memory?

public class Solution {


private int solveBit(int[] A, int bit) {
int sum = 0;
for (int i : A) {
sum += getBit(i, bit);
}
return sum % 3 == 0 ? 0 : 1;
}
private int getBit(int i, int bit) {
return (i & (1 << bit)) == 0 ? 0 : 1;
}
private int setBit(int i, int bit) {
return i | (1 << bit);
}
public int singleNumber(int[] A) {
int ret = 0;
for (int i = 0; i < Integer.SIZE; i++) {
if (solveBit(A, i) == 1) {
ret = setBit(ret, i);
}
}
return ret;
}
}
18. Given an array of integers, every element appears twice except for one. Find
that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it w
ithout using extra memory?
public class Solution {
public int singleNumber(int[] A) {
if (A == null) {
throw new NullPointerException();
}

int xors = 0;
for (int i : A) {
xors ^= i;
}
return xors;
}
}
19. There are N children standing in a line. Each child is assigned a rating val
ue.
You are giving candies to these children subjected to the following requirements
:
Each child must have at least one candy.
Children with a higher rating get more candies than their neighbors.
What is the minimum candies you must give?
public class Solution {
public int candy(int[] ratings) {
if (ratings == null) {
throw new NullPointerException();
} else if (ratings.length == 0) {
return 0;
}
int sum = 1;
int nextAdd = 2;
boolean increasing = ratings.length > 1 && ratings[1] > ratings[0];
int temp = Integer.MAX_VALUE;
for (int i = 1; i < ratings.length; i++) {
if ((increasing && ratings[i] > ratings[i - 1]) || (!increasing && r
atings[i] < ratings[i - 1])) {
sum += nextAdd;
nextAdd++;
if (!increasing && nextAdd == temp) {
sum++;
temp++;
}
} else {
if (increasing && ratings[i] < ratings[i - 1] && i < ratings.len
gth - 1 && ratings[i + 1] < ratings[i]) {
temp = nextAdd;
} else {
temp = Integer.MAX_VALUE;
}
increasing = i + 1 >= ratings.length || ratings[i + 1] > ratings
[i];
sum += ratings[i] > ratings[i - 1] && (i == ratings.length - 1 |
| ratings[i + 1] >= ratings[i]) ? 2 : 1;
nextAdd = ratings[i] > ratings[i - 1] && (i == ratings.length 1 || ratings[i + 1] >= ratings[i]) ? 3 : 2;
}
}

return sum;
}
}
20. There are N gas stations along a circular route, where the amount of gas at
station i is gas[i].
You have a car with an unlimited gas tank and it costs cost[i] of gas to travel
from station i to its next station (i+1). You begin the journey with an empty ta
nk at one of the gas stations.
Return the starting gas station's index if you can travel around the circuit onc
e, otherwise return -1.
Note:
The solution is guaranteed to be unique.
public class Solution {
private int nextIndex(int i, int[] gas) {
return i == gas.length - 1 ? 0 : i + 1;
}
private int getBestStart(int[] gas, int[] cost) {
int bestStart = 0;
int worstAmount = 0;
int currentCount = 0;
int current = 0;
for (int i = 0; i < 2 * gas.length + 3; i++) {
currentCount += gas[current] - cost[current];
currentCount = Math.min(currentCount, 0);
if (currentCount < worstAmount) {
worstAmount = currentCount;
bestStart = nextIndex(current, gas);
}
current = nextIndex(current, gas);
}
return bestStart;
}
private boolean canTraverseFrom(int start, int[] gas, int[] cost) {
int count = gas[start];
int i = start;
do {
count -= cost[i];
if (count < 0) {
return false;
}
i = nextIndex(i, gas);
count += gas[i];
} while (i != start);

return true;
}
public int canCompleteCircuit(int[] gas, int[] cost) {
if (gas == null || cost == null) {
throw new NullPointerException();
} else if (gas.length != cost.length || gas.length == 0) {
throw new IllegalArgumentException();
}
if (gas.length == 1) {
return gas[0] >= cost[0] ? 0 : -1;
}
int startTest = getBestStart(gas, cost);
return canTraverseFrom(startTest, gas, cost) ? startTest : -1;
}
}

21. Clone an undirected graph. Each node in the graph contains a label and a lis
t of its neighbors.
OJ's undirected graph serialization:
Nodes are labeled uniquely.
We use # as a separator for each node, and , as a separator for node label and e
ach neighbor of the node.
As an example, consider the serialized graph {0,1,2#1,2#2,2}.
The graph has a total of three nodes, and therefore contains three parts as sepa
rated by #.
First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
Second node is labeled as 1. Connect node 1 to node 2.
Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a se
lf-cycle.
Visually, the graph looks like the following:
1
/ \
/ \
0 --- 2
/ \
\_/
/**
* Definition for undirected graph.
* class UndirectedGraphNode {
*
int label;
*
List<UndirectedGraphNode> neighbors;
*
UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<Undirec
tedGraphNode>(); }
* };
*/
public class Solution {
private void cloneHelper(UndirectedGraphNode node, Map<Integer, UndirectedGr

aphNode> cloned) {
// if it's already cloned, do nothing
if (cloned.containsKey(node.label)) {
return;
}
UndirectedGraphNode newNode = new UndirectedGraphNode(node.label);
cloned.put(node.label, newNode);
// set neighbors
for (UndirectedGraphNode neighbor : node.neighbors) {
cloneHelper(neighbor, cloned);
newNode.neighbors.add(cloned.get(neighbor.label));
}
}
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
if (node == null) {
return null;
}
Map<Integer, UndirectedGraphNode> cloned = new HashMap<Integer, Undirect
edGraphNode>();
cloneHelper(node, cloned);
return cloned.get(node.label);
}
}

22. Given a string s, partition s such that every substring of the partition is
a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
For example, given s = "aab",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1
cut.
public class Solution {
public int minCut(String s) {
if (s.length() <= 1) {
return 0;
}
// cache[i] shows number of cuts needed for first i characters
int[] minCut = new int[s.length() + 1];
// maximum is 1 palindrome for each letter
for (int i = 0; i <= s.length(); i++) {
minCut[i] = i - 1;
}
// process all palindromes and update
for (int i = 0; i < s.length(); i++) {
// palindrome centered at i
for (int j = 0; i - j >= 0 && i + j < s.length() && s.charAt(i - j)
== s.charAt(i + j); j++) {
minCut[i + j + 1] = Math.min(minCut[i + j + 1], 1 + minCut[i - j

]);
}
//palindrome centerd at i + 0.5
for (int j = 1; i - j + 1 >= 0 && i + j < s.length() && s.charAt(i j + 1) == s.charAt(i + j); j++) {
minCut[i + j + 1] = Math.min(minCut[i + j + 1], 1 + minCut[i - j
+ 1]);
}
}
return minCut[s.length()];
}
}
23. Given a string s, partition s such that every substring of the partition is
a palindrome.
Return all possible palindrome partitioning of s.
For example, given s = "aab",
Return
[
["aa","b"],
["a","a","b"]
]

public class Solution {


private boolean isPalindrome(String s, int start, int end) {
while (start < end) {
if (s.charAt(start++) != s.charAt(end--)) {
return false;
}
}
return true;
}
private void partitionHelper(String s, int i, List<List<List<String>>> cache
) {
// need to try from j = 0 to i making a palindrome out of letters j thro
ugh i and adding that to everything on given cached list
for (int j = 0; j < i; j++) {
if (!isPalindrome(s, j, i - 1)) {
continue;
}
String lastPalindrome = s.substring(j, i);
List<List<String>> firstPartitionings = cache.get(j);
List<List<String>> ret = cache.get(i);
for (List<String> partitioning : firstPartitionings) {
List<String> newPartitioning = new ArrayList<String>(partitionin
g);
newPartitioning.add(lastPalindrome);

ret.add(newPartitioning);
}
}
}
// a partitioning into palindromes is List<String>
// maintain List<List<List<String>>> for which get(i) gives a List<List<Stri
ng>>
// this shows all the possible ways to partition the first i letters into pa
lindromes
// for each next letter read, populate based on previous
// when we finish last letter, we can return get(s.length())
public List<List<String>> partition(String s) {
if (s == null) {
throw new NullPointerException();
}
// inialize caching data structure
List<List<List<String>>> partitioningsOfFirstI = new ArrayList<>();
for (int i = 0; i <= s.length(); i++) {
partitioningsOfFirstI.add(new ArrayList<List<String>>());
}
partitioningsOfFirstI.get(0).add(new ArrayList<String>());
// solve for 1 through s.length()
for (int i = 1; i <= s.length(); i++) {
partitionHelper(s, i, partitioningsOfFirstI);
}
return partitioningsOfFirstI.get(s.length());
}
}
24. Given a 2D board containing 'X' and 'O', capture all regions surrounded by '
X'.
A region is captured by flipping all 'O's into 'X's in that surrounded region.
For example,
X X X X
X O O X
X X O X
X O X X
After running your function, the board should be:
X
X
X
X

X
X
X
O

X
X
X
X

X
X
X
X

public class Solution {


private void traverse(char[][] board, int i, int j) {
Queue<Integer> nextI = new LinkedList<>();
Queue<Integer> nextJ = new LinkedList<>();
nextI.add(i);
nextJ.add(j);

while (nextI.peek() != null) {


i = nextI.poll();
j = nextJ.poll();
if (board[i][j] != 'O') continue;
board[i][j] = 'q';
if (i + 1
); nextJ.add(j);}
if (i - 1
dd(j);}
if (j + 1
; nextJ.add(j + 1);}
if (j - 1
- 1);}
}
}

< board.length && board[i + 1][j] == 'O') {nextI.add(i + 1


>= 0 && board[i - 1][j] == 'O') {nextI.add(i - 1); nextJ.a
< board[0].length && board[i][j + 1] == 'O') {nextI.add(i)
>= 0 && board[i][j - 1] == 'O') {nextI.add(i); nextJ.add(j

public void solve(char[][] board) {


if (board == null) {
throw new NullPointerException();
}
if (board.length < 3 || board[0].length < 3) {
return;
}
for (int i = 0; i < board[0].length; i++) {
if (board[0][i] == 'O') traverse(board, 0, i);
if (board[board.length - 1][i] == 'O') traverse(board, board.length
- 1, i);
}
for (int i = 1; i < board.length - 1; i++) {
if (board[i][0] == 'O') traverse(board, i, 0);
if (board[i][board[0].length - 1] == 'O') traverse(board, i, board[0
].length - 1);
}
// decode
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] == 'O') board[i][j] = 'X';
if (board[i][j] == 'q') board[i][j] = 'O';
}
}
}
}

25. Given a binary tree containing digits from 0-9 only, each root-to-leaf path
could represent a number.
An example is the root-to-leaf path 1->2->3 which represents the number 123.
Find the total sum of all root-to-leaf numbers.

For example,
1
/ \
2 3
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.
Return the sum = 12 + 13 = 25.
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
static int sum;
private void sumNumbersHelper(TreeNode node, int soFar) {
if (node == null) {
return;
} else if (node.left == null && node.right == null) {
sum += 10 * soFar + node.val;
} else {
sumNumbersHelper(node.left, 10 * soFar + node.val);
sumNumbersHelper(node.right, 10 * soFar + node.val);
}
}
public int sumNumbers(TreeNode root) {
sum = 0;
sumNumbersHelper(root, 0);
return sum;
}
}
26. Given an unsorted array of integers, find the length of the longest consecut
ive elements sequence.
For example,
Given [100, 4, 200, 1, 3, 2],
The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.
Your algorithm should run in O(n) complexity.

public class Solution {


public int longestConsecutive(int[] num) {
if (num == null) {
throw new NullPointerException();
}
Map<Integer, Integer> counts = new HashMap<Integer, Integer>();

for (int i : num) {


counts.put(i, 1);
}
int max = 0;
for (int i : num) {
if (!counts.containsKey(i)) {
continue;
}
int numAbove = 0;
for (int j = i + 1; counts.containsKey(j); j++) {
numAbove += counts.get(j);
counts.remove(j);
}
counts.put(i, counts.get(i) + numAbove);
max = Math.max(max, counts.get(i));
}
return max;
}
}
27. Given two words (start and end), and a dictionary, find all shortest transfo
rmation sequence(s) from start to end, such that:
Only one letter can be changed at a time
Each intermediate word must exist in the dictionary
For example,
Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
Return
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
Note:
All words have the same length.
All words contain only lowercase alphabetic characters.

public class Solution {


private boolean oneLetterDiff(String s1, String s2) {
boolean foundDiff = false;
for (int i = 0; i < s1.length(); i++) {
if (s1.charAt(i) != s2.charAt(i)) {
if (foundDiff) {
return false;
} else {
foundDiff = true;
}

}
}
return foundDiff;
}
public List<List<String>> findLadders(String start, String end, Set<String>
dict) {
if (start == null || end == null || dict == null) {
throw new NullPointerException();
}
if (start.equals(end) || start.length() != end.length()) {
return new ArrayList<List<String>>();
}
Map<String, List<List<String>>> shortestPaths = new HashMap<>();
shortestPaths.put(start, new ArrayList<List<String>>());
shortestPaths.get(start).add(new ArrayList<String>());
shortestPaths.get(start).get(0).add(start);
Queue<String> q = new LinkedList<>();
q.add(start);
List<List<String>> ret = new ArrayList<List<String>>();
boolean foundOne = false;
int shortest = -1;
while (q.peek() != null) {
String current = q.remove();
if (foundOne && shortestPaths.get(current).get(0).size() > shortest)
{
break;
}
if (oneLetterDiff(current, end)) {
foundOne = true;
shortest = shortestPaths.get(current).get(0).size();
for (List<String> list : shortestPaths.get(current)) {
list.add(end);
ret.add(list);
}
}
// find neighbors if we still have not found 1 solution
if (foundOne) {
continue;
}
for (int prefixLength = 0; prefixLength < current.length(); prefixLe
ngth++) {
String prefix = current.substring(0, prefixLength);
String postfix = current.substring(prefixLength + 1);
for (char c = 'a'; c <= 'z'; c++) {
String s = prefix + c + postfix;
if (!dict.contains(s)) {

continue;
} else if (!shortestPaths.containsKey(s)) {
List<List<String>> solutions = new ArrayList<List<String
>>();
shortestPaths.put(s, solutions);
for (List<String> subSol : shortestPaths.get(current)) {
List<String> newSol = new ArrayList<String>(subSol);
newSol.add(s);
solutions.add(newSol);
}
q.add(s);
} else if (shortestPaths.get(current).get(0).size() + 1 == s
hortestPaths.get(s).get(0).size()) {
List<List<String>> solutions = shortestPaths.get(s);
for (List<String> subSol : shortestPaths.get(current)) {
List<String> newSol = new ArrayList<String>(subSol);
newSol.add(s);
solutions.add(newSol);
}
}
}
}
}
return ret;
}
}

28. Given two words (start and end), and a dictionary, find the length of shorte
st transformation sequence from start to end, such that:
Only one letter can be changed at a time
Each intermediate word must exist in the dictionary
For example,
Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.
Note:
Return 0 if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.
public class Solution {
// algorithm: BFS
// maintain a map from word to distanceFromStart
//
initialized with only start defined
//
if at the end target is not in map, return -1
//
else we return the distance to end from start

//
//
//
//

maintain a queue of nodes to traverse: initialized with only start


go through each node
first test if end is a neighbor, if it is return correct count
next for each word in the dictionary and not in map, see if it is a neig

hbor
// for each unvisited neighbor, add to queue and update distance map
private boolean oneLetterDiff(String s1, String s2) {
boolean foundDiff = false;
for (int i = 0; i < s1.length(); i++) {
if (s1.charAt(i) != s2.charAt(i)) {
if (foundDiff) {
return false;
} else {
foundDiff = true;
}
}
}
return foundDiff;
}
public int ladderLength(String start, String end, Set<String> dict) {
if (start == null || end == null || dict == null) {
throw new NullPointerException();
}
if (start.equals(end) || start.length() != end.length()) {
return 0;
}
Map<String, Integer> distances = new HashMap<>();
distances.put(start, 0);
Queue<String> q = new LinkedList<>();
q.add(start);
while (q.peek() != null) {
String current = q.remove();
if (oneLetterDiff(current, end)) {
return dict.contains(end) ? distances.get(current) + 2 : distanc
es.get(current) + 1;
}
// find neighbors
for (int prefixLength = 0; prefixLength < current.length(); prefixLe
ngth++) {
String prefix = current.substring(0, prefixLength);
String postfix = current.substring(prefixLength + 1);
for (char c = 'a'; c <= 'z'; c++) {
String s = prefix + c + postfix;
if (!distances.containsKey(s) && dict.contains(s)) {
q.add(s);
distances.put(s, distances.get(current) + 1);
}
}

}
}
return 0;
}
}

29. Given a string, determine if it is a palindrome, considering only alphanumer


ic characters and ignoring cases.
For example,
"A man, a plan, a canal: Panama" is a palindrome.
"race a car" is not a palindrome.
Note:
Have you consider that the string might be empty? This is a good question to ask
during an interview.
For the purpose of this problem, we define empty string as valid palindrome.
public class Solution {
public boolean isPalindrome(String s) {
int start;
int end;
for (start = 0; start < s.length() && !Character.isLetter(s.charAt(start
)) && !Character.isDigit(s.charAt(start)); start++);
for (end = s.length() - 1; end >= 0 && !Character.isLetter(s.charAt(end)
) && !Character.isDigit(s.charAt(end)); end--);
while (start < end) {
if (Character.toLowerCase(s.charAt(start)) != Character.toLowerCase(
s.charAt(end))) {
return false;
}
for (start = start + 1; start < s.length() && !Character.isLetter(s.
charAt(start)) && !Character.isDigit(s.charAt(start)); start++);
for (end = end - 1; end >= 0 && !Character.isLetter(s.charAt(end)) &
& !Character.isDigit(s.charAt(end)); end--);
}
return true;
}
}
30. Given a binary tree, find the maximum path sum.
The path may start and end at any node in the tree.
For example:
Given the below binary tree,
1

/ \
2 3
Return 6.
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private static int maxSum;
// return maximum branch sum starting at this node (must include this node)
private int traverse(TreeNode node) {
int left = 0;
int right = 0;
if (node.left != null) {
left = traverse(node.left);
}
if (node.right != null) {
right = traverse(node.right);
}
int maxAsRoot = node.val + Math.max(left, 0) + Math.max(right, 0);
maxSum = Math.max(maxSum, maxAsRoot);
int maxChildBranch = Math.max(left, right);
return node.val + Math.max(maxChildBranch, 0);
}
public int maxPathSum(TreeNode root) {
if (root == null) {
return 0;
}
maxSum = Integer.MIN_VALUE;
traverse(root);
return maxSum;
}
}
31. Say you have an array for which the ith element is the price of a given stoc
k on day i.
Design an algorithm to find the maximum profit. You may complete at most two tra
nsactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell
the stock before you buy again).

public class Solution {


public int maxProfit(int[] prices) {
if (prices.length < 2) {
return 0;
}
int[] bestStartingHere = new int[prices.length + 1];
int maxSoFar = prices[prices.length - 1];
for (int i = prices.length - 2; i >= 0; i--) {
bestStartingHere[i] = Math.max(bestStartingHere[i+1], maxSoFar - pri
ces[i]);
maxSoFar = Math.max(maxSoFar, prices[i]);
}
int minSoFar = prices[0];
int max = 0;
for (int i = 0; i < prices.length; i++) {
int guess = prices[i] - minSoFar + bestStartingHere[i + 1];
max = Math.max(max, guess);
minSoFar = Math.min(minSoFar, prices[i]);
}
return max;
}
}
32. Say you have an array for which the ith element is the price of a given stoc
k on day i.
Design an algorithm to find the maximum profit.
You may complete as many transactions as you like (ie, buy one and sell one sha
re of the stock multiple times).
However, you may not engage in multiple transactions at the same time (ie, you
must sell the stock before you buy again).
public class Solution {
public int maxProfit(int[] prices) {
int profit = 0;
boolean haveStock = false;
for (int i = 0; i < prices.length -1; i++) {
int currentPrice = prices[i];
int nextPrice = prices[i + 1];
if (haveStock && nextPrice < currentPrice) {
profit += currentPrice;
haveStock = false;
} else if (!haveStock && nextPrice > currentPrice) {
profit -= currentPrice;
haveStock = true;
}
}
if (haveStock) {
profit += prices[prices.length -1];
}

return profit;
}
}
33. Say you have an array for which the ith element is the price of a given stoc
k on day i.
If you were only permitted to complete at most one transaction (ie, buy one and
sell one share of the stock), design an algorithm to find the maximum profit.
public class Solution {
public int maxProfit(int[] prices) {
if (prices.length == 0) {
return 0;
}
int max = 0;
int minSoFar = prices[0];
for (int i = 1; i < prices.length; i++) {
max = Math.max(prices[i] - minSoFar, max);
minSoFar = Math.min(prices[i], minSoFar);
}
return max;
}
}
34. Given a triangle, find the minimum path sum from top to bottom. Each step yo
u may move to adjacent numbers on the row below.
For example, given the following triangle
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).
Note:
Bonus point if you are able to do this using only O(n) extra space, where n is t
he total number of rows in the triangle.
public class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
if (triangle == null) {
throw new NullPointerException();
} else if (triangle.size() == 0) {
throw new IllegalArgumentException();
}
List<Integer> minSum = new ArrayList<Integer>(triangle.get(triangle.size
() - 1));
for (int nextRowToSolve = triangle.size() - 2; nextRowToSolve >= 0; next
RowToSolve--) {
List<Integer> rowValues = triangle.get(nextRowToSolve);

for (int i = 0; i <= nextRowToSolve; i++) {


minSum.set(i, rowValues.get(i) + Math.min(minSum.get(i), minSum.
get(i + 1)));
}
}
return minSum.get(0);
}
}
35. Given an index k, return the kth row of the Pascal's triangle.
For example, given k = 3,
Return [1,3,3,1].
Note:
Could you optimize your algorithm to use only O(k) extra space?

public class Solution {


private List<Integer> getNextRow(List<Integer> prevRow) {
List<Integer> ret = new ArrayList<>();
ret.add(prevRow.get(0));
for (int i = 0; i < prevRow.size() - 1; i++) {
ret.add(prevRow.get(i) + prevRow.get(i + 1));
}
ret.add(prevRow.get(prevRow.size() - 1));
return ret;
}
public List<Integer> getRow(int rowIndex) {
if (rowIndex < 0) {
throw new IllegalArgumentException();
}
List<Integer> currentRow = new ArrayList<Integer>();
currentRow.add(1);
for (int i = 0; i < rowIndex; i++) {
currentRow = getNextRow(currentRow);
}
return currentRow;
}
}
36. Given numRows, generate the first numRows of Pascal's triangle.
For example, given numRows = 5,
Return
[
[1],
[1,1],

[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]

public class Solution {


private List<Integer> getNextRow(List<Integer> prevRow) {
List<Integer> ret = new ArrayList<>();
ret.add(prevRow.get(0));
for (int i = 0; i < prevRow.size() - 1; i++) {
ret.add(prevRow.get(i) + prevRow.get(i + 1));
}
ret.add(prevRow.get(prevRow.size() - 1));
return ret;
}
public List<List<Integer>> generate(int numRows) {
if (numRows < 0) {
throw new IllegalArgumentException();
}
List<List<Integer>> ret = new ArrayList<List<Integer>>();
if (numRows == 0) {
return ret;
}
List<Integer> firstRow = new ArrayList<Integer>();
firstRow.add(1);
ret.add(firstRow);
List<Integer> currentRow = firstRow;
for (int currentSize = 1; currentSize < numRows; currentSize++) {
currentRow = getNextRow(currentRow);
ret.add(currentRow);
}
return ret;
}
}
37. Follow up for problem "Populating Next Right Pointers in Each Node".
What if the given tree could be any binary tree? Would your previous solution st
ill work?
Note:
You may only use constant extra space.
For example,
Given the following binary tree,
1
/ \
2
3
/ \
\
4 5
7

After calling your function, the tree should look like:


1 -> NULL
/ \
2 -> 3 -> NULL
/ \
\
4-> 5 -> 7 -> NULL

/**
* Definition for binary tree with next pointer.
* public class TreeLinkNode {
*
int val;
*
TreeLinkNode left, right, next;
*
TreeLinkNode(int x) { val = x; }
* }
*/
public class Solution {
private TreeLinkNode getLeftmostChild(TreeLinkNode root) {
if (root == null) {
return null;
} else if (root.left != null) {
return root.left;
} else if (root.right != null) {
return root.right;
} else {
return getLeftmostChild(root.next);
}
}
// root right pointer must already be set when this function is called
// sets both next pointers of children and recurses on children
public void connect(TreeLinkNode root) {
if (root == null) {
return;
}
if (root.right != null) {
root.right.next = getLeftmostChild(root.next);
connect(root.right);
}
if (root.left != null) {
root.left.next = root.right == null ? getLeftmostChild(root.next) :
root.right;
connect(root.left);
}
}
}
38. Given a binary tree
struct TreeLinkNode {
TreeLinkNode *left;
TreeLinkNode *right;
TreeLinkNode *next;
}

Populate each next pointer to point to its next right node. If there is no next
right node, the next pointer should be set to NULL.
Initially, all next pointers are set to NULL.
Note:
You may only use constant extra space.
You may assume that it is a perfect binary tree (ie, all leaves are at the same
level, and every parent has two children).
For example,
Given the following perfect binary tree,
1
/ \
2
3
/ \ / \
4 5 6 7
After calling your function, the tree should look like:
1 -> NULL
/ \
2 -> 3 -> NULL
/ \ / \
4->5->6->7 -> NULL
Show Tags

/**
* Definition for binary tree with next pointer.
* public class TreeLinkNode {
*
int val;
*
TreeLinkNode left, right, next;
*
TreeLinkNode(int x) { val = x; }
* }
*/
public class Solution {
// root right pointer must already be set when this function is called
// sets both next pointers of children and recurses on children
public void connect(TreeLinkNode root) {
if (root == null) {
return;
}
if (root.left != null) {
root.left.next = root.right;
connect(root.left);
}
if (root.right != null) {
root.right.next = root.next == null ? null : root.next.left;
connect(root.right);
}
}
}

39. Given a string S and a string T, count the number of distinct subsequences o
f T in S.

A subsequence of a string is a new string which is formed from the original stri
ng by deleting some (can be none) of the characters without disturbing the relat
ive positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE
" while "AEC" is not).
Here is an example:
S = "rabbbit", T = "rabbit"
Return 3.

public class Solution {


private void numDistinctHelper(String S, int sIndex, String T, int tIndex, i
nt[][] cache) {
if (tIndex == T.length()) {
cache[sIndex][tIndex] = 1;
} else if (S.length() - sIndex < T.length() - tIndex) {
cache[sIndex][tIndex] = 0;
}
// check if cache is set
if (cache[sIndex][tIndex] >= 0) {
return;
}
assert sIndex < S.length();
assert tIndex < T.length();
// skip characers until they match
int sMatchIndex = sIndex;
while (S.charAt(sMatchIndex) != T.charAt(tIndex)) {
sMatchIndex++;
if (sMatchIndex == S.length()) {
cache[sIndex][tIndex] = 0;
return;
}
}
int count = 0;
// can skip character in S
numDistinctHelper(S, sMatchIndex + 1, T, tIndex, cache);
count += cache[sMatchIndex + 1][tIndex];
// or can use character in S
numDistinctHelper(S, sMatchIndex + 1, T, tIndex + 1, cache);
count += cache[sMatchIndex + 1][tIndex + 1];
cache[sIndex][tIndex] = count;
}
public int numDistinct(String S, String T) {
if (S == null || T == null) {
throw new NullPointerException();
}

int[][] cache = new int[S.length() + 1][T.length() + 1];


// set all values to -1
for (int i = 0; i <= S.length(); i++) {
for (int j = 0; j <= T.length(); j++) {
cache[i][j] = -1;
}
}
numDistinctHelper(S, 0, T, 0, cache);
return cache[0][0];
}
}
40. Given a binary tree, flatten it to a linked list in-place.
For example,
Given
1
/ \
2 5
/ \ \
3 4 6
The flattened tree should look like:
1
\
2
\
3
\
4
\
5
\
6
click to show hints.
Hints:
If you notice carefully in the flattened tree, each node's right child points to
the next node of a pre-order traversal.
Show Tags
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private void flattenHelper(TreeNode root, TreeNode tailPointsTo) {
if (root == null) {
return;
} else if (root.left == null && root.right == null) {

root.right = tailPointsTo;
return;
} else if (root.left == null) {
flattenHelper(root.right, tailPointsTo);
} else if (root.right == null) {
flattenHelper(root.left, tailPointsTo);
root.right = root.left;
root.left = null;
} else {
flattenHelper(root.left, root.right);
flattenHelper(root.right, tailPointsTo);
root.right = root.left;
root.left = null;
}
}
public void flatten(TreeNode root) {
flattenHelper(root, null);
}
}

41. Given a binary tree and a sum, find all root-to-leaf paths where each path's
sum equals the given sum.
For example:
Given the below binary tree and sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \
/ \
7
2 5 1
return
[
[5,4,11,2],
[5,8,4,5]
]
Show Tags

/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private void pathSumHelper(TreeNode node, int sum, List<Integer> currentPath
, List<List<Integer>> goodPaths) {
if (node == null) {
return;
} else if (node.left == null && node.right == null) {
if (node.val == sum) {

List<Integer> sol = new ArrayList<Integer>(currentPath);


sol.add(node.val);
goodPaths.add(sol);
}
return;
}
List<Integer> newCurrentPath = new ArrayList<Integer>(currentPath);
newCurrentPath.add(node.val);
int newSum = sum - node.val;
pathSumHelper(node.left, newSum, newCurrentPath, goodPaths);
pathSumHelper(node.right, newSum, newCurrentPath, goodPaths);
}
public List<List<Integer>> pathSum(TreeNode root, int sum) {
List<Integer> currentPath = new ArrayList<Integer>();
List<List<Integer>> ret = new ArrayList<List<Integer>>();
pathSumHelper(root, sum, currentPath, ret);
return ret;
}
}

42. Given a binary tree and a sum, determine if the tree has a root-to-leaf path
such that adding up all the values along the path equals the given sum.
For example:
Given the below binary tree and sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \
\
7
2
1
return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
if (root == null) {
return false;
} else if (root.left == null && root.right == null) {
return sum == root.val;
} else {

return hasPathSum(root.left, sum - root.val) || hasPathSum(root.righ


t, sum - root.val);
}
}
}

43. Given a binary tree, find its minimum depth.


The minimum depth is the number of nodes along the shortest path from the root n
ode down to the nearest leaf node.
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
} else if (root.right == null && root.left == null) {
return 1;
} else if (root.left == null) {
return minDepth(root.right) + 1;
} else if (root.right == null) {
return minDepth(root.left) + 1;
} else {
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
}
}
}
44. Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as a binary tree in w
hich the depth of the two subtrees of every node never differ by more than 1.
Show Tags

/**
* Definition for binary
* public class TreeNode
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) {
* }
*/
public class Solution {
// if tree rooted at

tree
{

val = x; }

root is balanced, returns height of root

// if unbalanced, returns -1
private int heightHelper(TreeNode root) {
if (root == null) {
return 0;
}
int leftHeight = heightHelper(root.left);
if (leftHeight == -1) {
return -1;
}
int rightHeight = heightHelper(root.right);
if (rightHeight == -1) {
return -1;
}
return Math.abs(leftHeight - rightHeight) <= 1 ? 1 + Math.max(leftHeight
, rightHeight) : -1;
}
public boolean isBalanced(TreeNode root) {
return heightHelper(root) != -1;
}
}

45. Given a singly linked list where elements are sorted in ascending order, con
vert it to a height balanced BST.
Show Tags
/**
* Definition for singly-linked list.
* public class ListNode {
*
int val;
*
ListNode next;
*
ListNode(int x) { val = x; next = null; }
* }
*/
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
// option 1: find middle (n time)
// then create root out of middle, recurse on both halves
// overall time is nlogn
// returns head of second list
// list must be at least 1 node
private ListNode split(ListNode head) {

ListNode prev = null;


ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
prev = slow;
slow = slow.next;
fast = fast.next.next;
}
prev.next = null;
return slow;
}
public TreeNode sortedListToBST(ListNode head) {
if (head == null) {
return null;
} else if (head.next == null) {
return new TreeNode(head.val);
}
ListNode head2 = split(head);
TreeNode root = new TreeNode(head2.val);
root.left = sortedListToBST(head);
root.right = sortedListToBST(head2.next);
return root;
}
}
46. Given an array where elements are sorted in ascending order, convert it to a
height balanced BST.
Show Tags
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private TreeNode sortedArrayToBstHelper(int[] num, int start, int end) {
if (start > end) {
return null;
} else if (start == end) {
return new TreeNode(num[start]);
}
// partition using middle element and recurse
int middle = (start + end) / 2;
TreeNode root = new TreeNode(num[middle]);
root.left = sortedArrayToBstHelper(num, start, middle - 1);
root.right = sortedArrayToBstHelper(num, middle + 1, end);
return root;
}

public TreeNode sortedArrayToBST(int[] num) {


if (num == null) {
throw new NullPointerException();
}
return sortedArrayToBstHelper(num, 0, num.length - 1);
}
}
47. Given a binary tree, return the bottom-up level order traversal of its nodes
' values. (ie, from left to right, level by level from leaf to root).
For example:
Given binary tree {3,9,20,#,#,15,7},
3
/ \
9 20
/ \
15 7
return its bottom-up level order traversal as:
[
[15,7],
[9,20],
[3]
]
confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on
OJ.
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
LinkedList<List<TreeNode>> levels = new LinkedList<List<TreeNode>>();
List<TreeNode> currentLevel = new ArrayList<TreeNode>();
if (root != null) {
currentLevel.add(root);
}
while (!currentLevel.isEmpty()) {
levels.addFirst(currentLevel);
List<TreeNode> nextLevel = new ArrayList<TreeNode>();
for (TreeNode node : currentLevel) {
if (node.left != null) {
nextLevel.add(node.left);
}
if (node.right != null) {

nextLevel.add(node.right);
}
}
currentLevel = nextLevel;
}
// need to extra ints
List<List<Integer>> ret = new ArrayList<List<Integer>>();
for (List<TreeNode> nodes : levels) {
List<Integer> retLevel = new ArrayList<Integer>();
for (TreeNode node : nodes) {
retLevel.add(node.val);
}
ret.add(retLevel);
}
return ret;
}
}

48. Given inorder and postorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private TreeNode buildTreeHelper(int[] inorder, int iIn, int[] postorder, in
t iPost, int size) {
if (size == 0) {
return null;
}
// find size of left subtree by looking at inorder
int leftSize = 0;
while (inorder[iIn + leftSize] != postorder[iPost + size - 1]) {
leftSize++;
}
TreeNode root = new TreeNode(postorder[iPost + size - 1]);
root.left = buildTreeHelper(inorder, iIn, postorder, iPost, leftSize);
root.right = buildTreeHelper(inorder, iIn + leftSize + 1, postorder, iPo
st + leftSize, size - leftSize - 1);
return root;
}

public TreeNode buildTree(int[] inorder, int[] postorder) {


if (inorder == null || postorder == null) {
throw new NullPointerException();
} else if (inorder.length != postorder.length) {
throw new IllegalArgumentException();
}
return buildTreeHelper(inorder, 0, postorder, 0, inorder.length);
}
}
49. Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private TreeNode buildTreeHelper(int[] preorder, int iPre, int[] inorder, in
t iIn, int length) {
if (length == 0) {
return null;
}
if (length == 1) {
return new TreeNode(preorder[iPre]);
}
TreeNode root = new TreeNode(preorder[iPre]);
int leftLength = 0;
while (inorder[iIn + leftLength] != preorder[iPre]) {
leftLength++;
}
root.left = buildTreeHelper(preorder, iPre + 1, inorder, iIn, leftLength
);
root.right = buildTreeHelper(preorder, iPre + 1 + leftLength, inorder, i
In + leftLength + 1, length - 1 - leftLength);
return root;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || inorder == null) {
throw new NullPointerException();
}
if (preorder.length != inorder.length) {
throw new IllegalArgumentException();
}

return buildTreeHelper(preorder, 0, inorder, 0, preorder.length);


}
}

50. Given a binary tree, find its maximum depth.


The maximum depth is the number of nodes along the longest path from the root no
de down to the farthest leaf node.
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public int maxDepth(TreeNode root) {
return root == null ? 0 : 1 + Math.max(maxDepth(root.left), maxDepth(roo
t.right));
}
}
51. Given a binary tree, return the zigzag level order traversal of its nodes' v
alues. (ie, from left to right, then right to left for the next level and altern
ate between).
For example:
Given binary tree {3,9,20,#,#,15,7},
3
/ \
9 20
/ \
15 7
return its zigzag level order traversal as:
[
[3],
[20,9],
[15,7]
]
confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on
OJ.
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {

public List<List<Integer>> zigzagLevelOrder(TreeNode root) {


List<List<Integer>> ret = new ArrayList<>();
if (root == null) {
return ret;
}
boolean goingRight = true;
Stack<TreeNode> currentLevel = new Stack<>();
currentLevel.push(root);
while (!currentLevel.isEmpty()) {
List<Integer> currentLevelInts = new ArrayList<>();
ret.add(currentLevelInts);
Stack<TreeNode> nextLevel = new Stack<>();
while (!currentLevel.isEmpty()) {
TreeNode currentNode = currentLevel.pop();
currentLevelInts.add(currentNode.val);
if (goingRight) {
if (currentNode.left != null) {
nextLevel.push(currentNode.left);
}
if (currentNode.right != null) {
nextLevel.push(currentNode.right);
}
} else {
if (currentNode.right != null) {
nextLevel.push(currentNode.right);
}
if (currentNode.left != null) {
nextLevel.push(currentNode.left);
}
}
}
goingRight = !goingRight;
currentLevel = nextLevel;
}
return ret;
}
}
52. Given a binary tree, return the level order traversal of its nodes' values.
(ie, from left to right, level by level).
For example:
Given binary tree {3,9,20,#,#,15,7},
3
/ \
9 20
/ \
15 7
return its level order traversal as:
[
[3],
[9,20],
[15,7]

]
confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on
OJ.
Show Tags
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ret = new ArrayList<List<Integer>>();
if (root == null) {
return ret;
}
List<TreeNode> currentLevel = new ArrayList<TreeNode>();
currentLevel.add(root);
while (!currentLevel.isEmpty()) {
List<Integer> ints = new ArrayList<Integer>();
ret.add(ints);
List<TreeNode> nextLevel = new ArrayList<TreeNode>();
for (TreeNode node : currentLevel) {
if (node.left != null) {
nextLevel.add(node.left);
}
if (node.right != null) {
nextLevel.add(node.right);
}
ints.add(node.val);
}
currentLevel = nextLevel;
}
return ret;
}
}
53. Given a binary tree, check whether it is a mirror of itself (ie, symmetric a
round its center).
For example, this binary tree is symmetric:
1
/ \
2

/ \ / \
3 4 4 3
But the following is not:
1
/ \
2 2
\ \
3
3
Note:
Bonus points if you could solve it both recursively and iteratively.
confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on
OJ.
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private boolean isMirror(TreeNode r1, TreeNode r2) {
if (r1 == null || r2 == null) {
return r1 == null && r2 == null;
}
return r1.val == r2.val && isMirror(r1.left, r2.right) && isMirror(r1.ri
ght, r2.left);
}
public boolean isSymmetric(TreeNode root) {
return root == null || isMirror(root.left, root.right);
}
}
54. Given two binary trees, write a function to check if they are equal or not.
Two binary trees are considered equal if they are structurally identical and the
nodes have the same value.
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null || q == null) {
return p == null && q == null;
} else {
return p.val == q.val && isSameTree(p.left, q.left) && isSameTree(p.
right, q.right);

}
}
}
55. Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Note:
A solution using O(n) space is pretty straight forward. Could you devise a const
ant space solution?
confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on
OJ.
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private TreeNode getBadNode(TreeNode root, int min, int max) {
if (root == null) {
return null;
}
if (root.val < min || root.val > max) {
return root;
}
TreeNode badNodeLeft = getBadNode(root.left, min, root.val);
TreeNode badNodeRight = getBadNode(root.right, root.val, max);
if (badNodeLeft != null) {
return badNodeLeft;
} else if (badNodeRight != null) {
return badNodeRight;
} else {
return null;
}
}
private TreeNode getMax(TreeNode root) {
if (root == null) {
return null;
}
TreeNode maxLeft = getMax(root.left);
TreeNode maxRight = getMax(root.right);
TreeNode max = root;
if (maxLeft != null && maxLeft.val > max.val) {
max = maxLeft;
}

if (maxRight != null && maxRight.val > max.val) {


max = maxRight;
}
return max;
}
private TreeNode getMin(TreeNode root) {
if (root == null) {
return null;
}
TreeNode minLeft = getMin(root.left);
TreeNode minRight = getMin(root.right);
TreeNode min = root;
if (minLeft != null && minLeft.val < min.val) {
min = minLeft;
}
if (minRight != null && minRight.val < min.val) {
min = minRight;
}
return min;
}
private void
int temp
t1.val =
t2.val =
}

swapVals(TreeNode t1, TreeNode t2) {


= t1.val;
t2.val;
temp;

public void recoverTree(TreeNode root) {


if (root == null) {
return;
}
TreeNode badLeft = getBadNode(root.left, Integer.MIN_VALUE, root.val);
TreeNode badRight = getBadNode(root.right, root.val, Integer.MAX_VALUE);
if (badLeft != null && badRight != null) {
swapVals(badLeft, badRight);
} else if (badLeft != null) {
TreeNode leftMax = getMax(root.left);
if (leftMax.val > root.val) {
swapVals(root, leftMax);
} else {
recoverTree(root.left);
}
} else if (badRight != null) {
TreeNode rightMin = getMin(root.right);
if (rightMin.val < root.val) {
swapVals(root, rightMin);
} else {
recoverTree(root.right);
}

}
}
}
56. Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
The left subtree of a node contains only nodes with keys less than the node's ke
y.
The right subtree of a node contains only nodes with keys greater than the node'
s key.
Both the left and right subtrees must also be binary search trees.
confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on
OJ.
OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' si
gnifies a path terminator where no node exists below.
Here's an example:
1
/ \
2 3
/
4
\
5
The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}".
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private boolean isValidHelper(TreeNode root, int min, int max) {
if (root == null) {
return true;
}
return root.val > min && root.val < max && isValidHelper(root.left, min,
root.val) && isValidHelper(root.right, root.val, max);
}
public boolean isValidBST(TreeNode root) {
return isValidHelper(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
}
57. Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2
.

For example,
Given:
s1 = "aabcc",
s2 = "dbbca",
When s3 = "aadbbcbcac", return true.
When s3 = "aadbbbaccc", return false.
public class Solution {
// i1 + i2 must equal i3
private void isInterleaveHelper(String s1, int i1, String s2, int i2, String
s3, int i3, List<Map<Integer, Boolean>> caches) {
// first attempt cache lookup
if (caches.get(i1).containsKey(i2)) {
return;
}
// handle when at least 1 string is exhausted
if (i3 == s3.length()) {
caches.get(i1).put(i2, true);
return;
} else if (i1 == s1.length()) {
caches.get(i1).put(i2, s2.substring(i2).equals(s3.substring(i3)));
return;
} else if (i2 == s2.length()) {
caches.get(i1).put(i2, s1.substring(i1).equals(s3.substring(i3)));
return;
}
// try matching character from s1
if (s1.charAt(i1) == s3.charAt(i3)) {
isInterleaveHelper(s1, i1 + 1, s2, i2, s3, i3 + 1, caches);
if (caches.get(i1 + 1).get(i2)) {
caches.get(i1).put(i2, true);
return;
}
}
// try matching character from s2
if (s2.charAt(i2) == s3.charAt(i3)) {
isInterleaveHelper(s1, i1, s2, i2 + 1, s3, i3 + 1, caches);
if (caches.get(i1).get(i2 + 1)) {
caches.get(i1).put(i2, true);
return;
}
}
// if all attempts fail, we return false
caches.get(i1).put(i2, false);
return;
}
public boolean isInterleave(String s1, String s2, String s3) {
if (s1 == null || s2 == null || s3 == null) {
throw new NullPointerException();
}

if (s1.length() + s2.length() != s3.length()) {


return false;
}
// define cache for each index in s1
List<Map<Integer, Boolean>> caches = new ArrayList<Map<Integer, Boolean>
>();
for (int i = 0; i <= s1.length(); i++) {
caches.add(new HashMap<Integer, Boolean>());
}
isInterleaveHelper(s1, 0, s2, 0, s3, 0, caches);
return caches.get(0).get(0);
}
}
58. Given n, generate all structurally unique BST's (binary search trees) that s
tore values 1...n.
For example,
Given n = 3, your program should return all 5 unique BST's shown below.
1

3
\

/
3

2
/

2
/ \

/
1

1
\
3

\
2
1
2
3
confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on
OJ.
OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' si
gnifies a path terminator where no node exists below.
Here's an example:
1
/ \
2 3
/
4
\
5
The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}".
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; left = null; right = null; }
* }
*/
public class Solution {

private TreeNode copyTreeAddingX(TreeNode root, int x) {


if (root == null) {
return root;
}
TreeNode newRoot = new TreeNode(root.val + x);
newRoot.left = copyTreeAddingX(root.left, x);
newRoot.right = copyTreeAddingX(root.right, x);
return newRoot;
}
public List<TreeNode> generateTrees(int n) {
// cache.get(i) = list of all trees of size i
List<List<TreeNode>> cache = new ArrayList<List<TreeNode>>();
for (int i = 0; i <= n; i++) {
cache.add(new ArrayList<TreeNode>());
}
// solve for size 0
cache.get(0).add(null);
// solving for all trees of size i
for (int i = 1; i <= n; i++) {
// try each possible root
for (int r = 1; r <= i; r++) {
// try each possible left subtree
for (TreeNode left : cache.get(r - 1)) {
// try each possible right subtree
for (TreeNode right : cache.get(i - r)) {
TreeNode newRoot = new TreeNode(r);
newRoot.left = left;
newRoot.right = copyTreeAddingX(right, r);
cache.get(i).add(newRoot);
}
}
}
}
return cache.get(n);
}
}
59. Given n, how many structurally unique BST's (binary search trees) that store
values 1...n?
For example,
Given n = 3, there are a total of 5 unique BST's.
1

3
\
3

/
2

/
/
1

2
/ \

/
1

1
\

1
\
3

2
\

public class Solution {

public int numTrees(int n) {


if (n < 0) {
throw new IllegalArgumentException();
}
int[] sol = new int[n + 1];
sol[0] = 1;
for (int i = 1; i <= n; i++) {
int left = i - 1;
int sum = 0;
for (int j = 0; j <= left; j++) {
sum += sol[j] * sol[left - j];
}
sol[i] = sum;
}
return sol[n];
}
}
60. Given a binary tree, return the inorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3},
1
\
2
/
3
return [1,3,2].
Note: Recursive solution is trivial, could you do it iteratively?
confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on
OJ.
/**
* Definition for binary tree
* public class TreeNode {
*
int val;
*
TreeNode left;
*
TreeNode right;
*
TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
if (root == null) {
return ret;
}
Stack<TreeNode> s = new Stack<>();
TreeNode current = root;
while(true) {

if (current == null) {
if (s.isEmpty()) {
break;
} else {
current = s.pop();
ret.add(current.val);
current = current.right;
}
} else {
s.push(current);
current = current.left;
}
}
return ret;
}
}
61. Given a string containing only digits, restore it by returning all possible
valid IP address combinations.
For example:
Given "25525511135",
return ["255.255.11.135", "255.255.111.35"]. (Order does not matter)
public class Solution {
// n: numer of sections of IP address remaining
// i: starting index in S
public List<String> restoreHelper(String s, int i, int n) {
List<String> ret = new ArrayList<>();
// base case: n is 0
if (n == 0) {
if (i == s.length()) {
ret.add("");
}
return ret;
}
// we may now assume n >= 1
int charsLeft = s.length() - i;
if (charsLeft == 1) {
if (n == 1) {
ret.add(Character.toString(s.charAt(i)));
}
} else if (charsLeft == 2) {
int first = s.charAt(i) - '0';
int second = s.charAt(i + 1) - '0';
if (n == 1 && first != 0) {
ret.add(Integer.toString(first) + Integer.toString(second));
} else if (n == 2) {
ret.add(Integer.toString(first) + "." + Integer.toString(second)
);
}

} else if (charsLeft >= 3) {


int first = s.charAt(i) - '0';
int second = s.charAt(i + 1) - '0';
int third = s.charAt(i + 2) - '0';
// if n is 1, we have to use all three and not put a period at the e
nd
if (n == 1) {
if (first != 0 && 100 * first + 10 * second + third <= 255 && ch
arsLeft == 3) {
ret.add(Integer.toString(first) + Integer.toString(second) +
Integer.toString(third));
}
return ret;
}
// try with 1 char
List<String> rest = restoreHelper(s, i + 1, n - 1);
for (String t : rest) {
ret.add(Integer.toString(first) + "." + t);
}
// try with 2 char
if (first != 0) {
rest = restoreHelper(s, i + 2, n - 1);
for (String t : rest) {
ret.add(Integer.toString(first) + Integer.toString(second) +
"." + t);
}
}
// try with 3 char
if (first != 0 && 100 * first + 10 * second + third <= 255) {
rest = restoreHelper(s, i + 3, n - 1);
for (String t : rest) {
ret.add(Integer.toString(first) + Integer.toString(second) +
Integer.toString(third) + "." + t);
}
}
}
return ret;
}
public List<String> restoreIpAddresses(String s) {
if (s == null) {
throw new NullPointerException();
}
return restoreHelper(s, 0, 4);
}
}
62. Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:

Given 1->2->3->4->5->NULL, m = 2 and n = 4,


return 1->4->3->2->5->NULL.
Note:
Given m, n satisfy the following condition:
1 m n length of list.
/**
* Definition for singly-linked list.
* public class ListNode {
*
int val;
*
ListNode next;
*
ListNode(int x) {
*
val = x;
*
next = null;
*
}
* }
*/
public class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
if (m < 1 || n < m) {
throw new IllegalArgumentException();
}
ListNode sentinel = new ListNode(0);
sentinel.next = head;
ListNode current = sentinel;
// move to node before where we want to start reversing
for (int i = 1; i < m; i++) {
current = current.next;
}
// reverse some nodes
ListNode beforeReverse = current;
current = current.next;
ListNode prev = current;;
current = current.next;
for (int i = m; i < n; i++) {
ListNode next = current.next;
current.next = prev;
prev = current;
current = next;
}
beforeReverse.next.next = current;
beforeReverse.next = prev;
return sentinel.next;
}
}
63. Given a collection of integers that might contain duplicates, S, return all
possible subsets.
Note:
Elements in a subset must be in non-descending order.

The solution set must not contain duplicate subsets.


For example,
If S = [1,2,2], a solution is:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
public class Solution {
private boolean isBitSet(int num, int bit) {
return (num & (1 << bit)) != 0;
}
public List<List<Integer>> subsetsWithDup(int[] num) {
if (num == null) {
throw new NullPointerException();
}
List<List<Integer>> ret = new ArrayList<>();
if (num.length == 0) {
return ret;
}
Arrays.sort(num);
int max = (1 << num.length) - 1;
// bits of i represent which elements of noDups to include
outer:
for (int i = 0; i <= max; i++) {
List<Integer> sol = new ArrayList<>();
int lastSkipped = num[0] - 1;
for (int j = 0; j < num.length; j++) {
if (isBitSet(i, j)) {
if (lastSkipped == num[j]) {
continue outer;
}
sol.add(num[j]);
} else {
lastSkipped = num[j];
}
}
ret.add(sol);
}
return ret;
}
}

64. A message containing letters from A-Z is being encoded to numbers using the
following mapping:

'A' -> 1
'B' -> 2
...
'Z' -> 26
Given an encoded message containing digits, determine the total number of ways t
o decode it.
For example,
Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12).
The number of ways decoding "12" is 2.
public class Solution {
private int numDecodingsHelper(String s, int i, int[] cache) {
int first = s.charAt(i) - '0';
int second = s.charAt(i + 1) - '0';
if (first == 0) {
return 0;
} else if (first == 1 || (first == 2 && second < 7)) {
return cache[i + 1] + cache[i + 2];
} else {
return cache[i + 1];
}
}
public int numDecodings(String s) {
if (s == null) {
throw new NullPointerException();
}
if (s.length() == 0) {
return 0;
}
int[] cache = new int[s.length() + 1];
cache[s.length()] = 1;
cache[s.length() - 1] = s.charAt(s.length() - 1) == '0' ? 0 : 1;
for (int i = s.length() - 2; i >= 0; i--) {
cache[i] = numDecodingsHelper(s, i, cache);
}
return cache[0];
}
}
65. The gray code is a binary numeral system where two successive values differ
in only one bit.
Given a non-negative integer n representing the total number of bits in the code
, print the sequence of gray code. A gray code sequence must begin with 0.
For example, given n = 2, return [0,1,3,2]. Its gray code sequence is:
00
01
11
10

0
1
3
2

Note:
For a given n, a gray code sequence is not uniquely defined.
For example, [0,2,3,1] is also a valid gray code sequence according to the above
definition.
For now, the judge is able to judge based on one instance of gray code sequence.
Sorry about that.
public class Solution {
public List<Integer> grayCode(int n) {
if (n < 0) {
throw new IllegalArgumentException();
}
List<Integer> ret = new ArrayList<>();
ret.add(0);
// solve gray code problem for 1 bit up through n bits
for (int i = 1; i <= n; i++) {
int prevSize = ret.size();
for (int j = prevSize - 1; j >= 0; j--) {
int prev = ret.get(j);
ret.add(prev + (1 << (i - 1)));
}
}
return ret;
}
}
66. Given two sorted integer arrays A and B, merge B into A as one sorted array.
Note:
You may assume that A has enough space (size that is greater or equal to m + n)
to hold additional elements from B.
The number of elements initialized in A and B are m and n respectively.

public class Solution {


public void merge(int A[], int m, int B[], int n) {
if (A == null || B == null) {
throw new NullPointerException();
}
if (A.length < m + n) {
throw new IllegalArgumentException();
}
int nextPos = m + n - 1;
m--;
n--;
while (m >= 0 && n >= 0) {
if (A[m] > B[n]) {
A[nextPos--] = A[m--];

} else {
A[nextPos--] = B[n--];
}
}
while (n >= 0) {
A[nextPos--] = B[n--];
}
}
}

67. Given a string s1, we may represent it as a binary tree by partitioning it t


o two non-empty substrings recursively.
Below is one possible representation of s1 = "great":
great
\
eat
/ \
g r e at
/ \
a t
To scramble the string, we may choose any non-leaf node and swap its two childre
n.
/
gr
/ \

For example, if we choose the node "gr" and swap its two children, it produces a
scrambled string "rgeat".
rgeat
\
eat
/ \
r g e at
/ \
a t
We say that "rgeat" is a scrambled string of "great".
/
rg
/ \

Similarly, if we continue to swap the children of nodes "eat" and "at", it produ
ces a scrambled string "rgtae".
rgtae
\
tae
/ \
r g ta e
/ \
t a
We say that "rgtae" is a scrambled string of "great".
/
rg
/ \

Given two strings s1 and s2 of the same length, determine if s2 is a scrambled s


tring of s1.
public class Solution {
private boolean isPermutation(String s1, String s2) {
if (s1.length() != s2.length()) {
return false;

}
Map<Character, Integer> counts = new HashMap<Character, Integer>();
for (char c : s1.toCharArray()) {
counts.put(c, counts.containsKey(c) ? counts.get(c) + 1 : 1);
}
for (char c : s2.toCharArray()) {
if (!counts.containsKey(c)) {
return false;
} else if (counts.get(c) <= 0) {
return false;
}
counts.put(c, counts.get(c) - 1);
}
return true;
}
private boolean isScrambleHelper(String s1, int s1Start, String s2, int s2St
art, int length) {
if (length == 0) {
return true;
} else if (length == 1) {
return s1.charAt(s1Start) == s2.charAt(s2Start);
}
// find leftLength such that all characters in left of s2 come either be
fore/after all characters in right of s2
for (int leftLength = 1; leftLength < length; leftLength++) {
if (isPermutation(s1.substring(s1Start, s1Start + leftLength), s2.su
bstring(s2Start, s2Start + leftLength))) {
if (isScrambleHelper(s1, s1Start, s2, s2Start, leftLength)
&& isScrambleHelper(s1, s1Start + leftLength, s2, s2Start +
leftLength, length - leftLength)) {
return true;
}
}
if (isPermutation(s1.substring(s1Start + length - leftLength, s1Star
t + length), s2.substring(s2Start, s2Start + leftLength))) {
if (isScrambleHelper(s1, s1Start + length - leftLength, s2, s2St
art, leftLength)
&& isScrambleHelper(s1, s1Start, s2, s2Start + leftLength, l
ength - leftLength)) {
return true;
}
}
}
return false;
}
// determine if s2 is a scrambled string of s1
public boolean isScramble(String s1, String s2) {
if (s1 == null || s2 == null) {
throw new NullPointerException();
}

if (s1.length() != s2.length()) {
return false;
}
return isScrambleHelper(s1, 0, s2, 0, s1.length());
}
}
68. Given a linked list and a value x, partition it such that all nodes less tha
n x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two
partitions.
For example,
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.
/**
* Definition for singly-linked list.
* public class ListNode {
*
int val;
*
ListNode next;
*
ListNode(int x) {
*
val = x;
*
next = null;
*
}
* }
*/
public class Solution {
public ListNode partition(ListNode head, int x) {
ListNode lessSentinel = new ListNode(0);
ListNode lessTail = lessSentinel;
ListNode greaterSentinel = new ListNode(0);
ListNode greaterTail = greaterSentinel;
ListNode next;
for (ListNode current = head; current != null; current = next) {
next = current.next;
if (current.val < x) {
lessTail.next = current;
lessTail = current;
} else {
greaterTail.next = current;
greaterTail = current;
}
current.next = null;
}
lessTail.next = greaterSentinel.next;
return lessSentinel.next;
}
}

69. Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle
containing all ones and return its area.
public class Solution {
private int[][] getHeightMatrix(char[][] matrix) {
assert matrix.length > 0;
int[][] height = new int[matrix.length][matrix[0].length];
// for top row, height is simply equal to 1 or 0
for (int j = 0; j < matrix[0].length; j++) {
height[0][j] = matrix[0][j] == '1' ? 1 : 0;
}
// for each subsequent row, calculate dependent on above height
for (int i = 1; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
height[i][j] = matrix[i][j] == '1' ? height[i - 1][j] + 1 : 0;
}
}
return height;
}
public int maximalRectangle(char[][] matrix) {
if (matrix == null) {
throw new NullPointerException();
}
int rows = matrix.length;
int cols = matrix.length > 0 ? matrix[0].length : 0;
if (rows == 0 || cols == 0) {
return 0;
}
// create height matrix: number of 1s at or directly above matrix[i][j]
int[][] height = getHeightMatrix(matrix);
int max = 0;
// i is the potential base row of the rectangle
for (int i = 0; i < rows; i++) {
Stack<Integer> indices = new Stack<>();
for (int j = 0; j < cols; j++) {
int currH = height[i][j];
if (indices.isEmpty() || currH >= height[i][indices.peek()]) {
indices.push(j);
} else {
while (!indices.isEmpty() && currH < height[i][indices.peek(
)]) {
int rectH = height[i][indices.pop()];
int leftmost = indices.isEmpty() ? 0 : indices.peek() +
1;
int rightmost = j - 1;
int rectW = rightmost - leftmost + 1;
max = Math.max(max, rectH * rectW);
}

indices.push(j);
}
}
while (!indices.isEmpty()) {
int rectH = height[i][indices.pop()];
int leftmost = indices.isEmpty() ? 0 : indices.peek() + 1;
int rightmost = cols - 1;
int rectW = rightmost - leftmost + 1;
max = Math.max(max, rectH * rectW);
}
}
return max;
}
}
70. 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.
http://www.leetcode.com/wp-content/uploads/2012/04/histogram.png
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].
http://www.leetcode.com/wp-content/uploads/2012/04/histogram_area.png
The largest rectangle is shown in the shaded area, which has area = 10 unit.
For example,
Given height = [2,1,5,6,2,3],
return 10.
Show Tags
public class Solution {
// at each bar B, want to compute max area with that bar as min
// need to find leftmost bar at least as high as B and rightmost bar at leas
t as high as B
// maintain a stack
// when encounter bar B
// if stack is empty or B is larger than top of stack, push B
// bottom of stack is smallest bars
// if B is smllaer than top of stack, start popping stuff off the stack
// for everything popped off, letftmost higher bar is thing under it + 1 and
rightmost highest is i-1
// now push B on the stack
// 5 9 8 4 7
public int largestRectangleArea(int[] height) {
if (height == null) {
throw new NullPointerException();
}
Stack<Integer> indices = new Stack<>();
int max = 0;

for (int i = 0; i < height.length; i++) {


int h = height[i];
if (indices.isEmpty() || h >= height[indices.peek()]) {
indices.push(i);
} else {
while (!indices.isEmpty() && h < height[indices.peek()]) {
int lowestIndex = indices.pop();
int rectLeft = indices.isEmpty() ? 0 : indices.peek() + 1;
int rectRight = i - 1;
int rectWidth = rectRight - rectLeft + 1;
int rectHeight = height[lowestIndex];
max = Math.max(max, rectWidth * rectHeight);
}
indices.push(i);
}
}
while (!indices.isEmpty()) {
int lowestIndex = indices.pop();
int rectLeft = indices.isEmpty() ? 0 : indices.peek() + 1;
int rectRight = height.length - 1;
int rectWidth = rectRight - rectLeft + 1;
int rectHeight = height[lowestIndex];
max = Math.max(max, rectWidth * rectHeight);
}
return max;
}
}
71. Given a sorted linked list, delete all nodes that have duplicate numbers, le
aving only distinct numbers from the original list.
For example,
Given 1->2->3->3->4->4->5, return 1->2->5.
Given 1->1->1->2->3, return 2->3.
/**
* Definition for singly-linked list.
* public class ListNode {
*
int val;
*
ListNode next;
*
ListNode(int x) {
*
val = x;
*
next = null;
*
}
* }
*/
public class Solution {
public ListNode deleteDuplicates(ListNode head) {
// algorithm:
// keep track of current tail and a poiner for current
// if current null, tail.next = null
// if current single node, hook it up
// if current multiple nodes, advance current
ListNode sentinel = new ListNode(0);

ListNode tail = sentinel;


ListNode current = head;
while (current != null) {
if (current.next != null && current.val == current.next.val) {
for (current = current.next; current.next != null && current.nex
t.val == current.val; current = current.next);
current = current.next;
} else {
tail.next = current;
tail = tail.next;
current = current.next;
}
}
tail.next = null;
return sentinel.next;
}
}
72. Given a sorted linked list, delete all duplicates such that each element app
ear only once.
For example,
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.
/**
* Definition for singly-linked list.
* public class ListNode {
*
int val;
*
ListNode next;
*
ListNode(int x) {
*
val = x;
*
next = null;
*
}
* }
*/
public class Solution {
public ListNode deleteDuplicates(ListNode head) {
if (head == null) {
return null;
}
ListNode current = head;
while (current.next != null) {
if (current.val == current.next.val) {
current.next = current.next.next;
} else {
current = current.next;
}
}
return head;
}
}

73. Follow up for "Search in Rotated Sorted Array":


What if duplicates are allowed?
Would this affect the run-time complexity? How and why?
Write a function to determine if a given target is in the array.
public class Solution {
//8 8 8 7 8 8 9 9 8
// worst case run-time is now linear
// for example if array is 8 8 8 8 8 8 7 8 8 8 8 and we are searching for 7
public boolean search(int[] A, int target) {
// algorithm:
// 1) check if A is null
// 2) check if A is 0/1/2 elements (?)
// 3) if ends are equal but not target, search linearly
// 4) else run binarySearchRotatedHelper on whole array
// 5) binarySearchRotatedHelper: check for ends equal
//
run binary search assuming ends not equal
// test: will OJ accept linear
if (A == null) {
throw new NullPointerException();
}
for (int i : A) {
if (i == target) {
return true;
}
}
return false;
}
}
74. Follow up for "Remove Duplicates":
What if duplicates are allowed at most twice?
For example,
Given sorted array A = [1,1,1,2,2,3],
Your function should return length = 5, and A is now [1,1,2,2,3].
public class Solution {
public int removeDuplicates(int[] A) {
if (A == null) {
throw new NullPointerException();
}
int toIndex = 0;
int fromIndex = 0;
while (fromIndex < A.length) {
A[toIndex++] = A[fromIndex++];

if (fromIndex < A.length && A[fromIndex] == A[fromIndex - 1]) {


A[toIndex++] = A[fromIndex++];
}
while (fromIndex < A.length && A[fromIndex] == A[fromIndex - 1]) {
fromIndex++;
}
}
return toIndex;
}
}
75. Given a 2D board and a word, find if the word exists in the grid.
The word can be constructed from letters of sequentially adjacent cell, where "a
djacent" cells are those horizontally or vertically neighboring. The same letter
cell may not be used more than once.
For example,
Given board =
[
["ABCE"],
["SFCS"],
["ADEE"]
]
word = "ABCCED", -> returns true,
word = "SEE", -> returns true,
word = "ABCB", -> returns false.
class Coordinate {
int x;
int y;
public Coordinate(int x, int y) {
this.x = x;
this.y = y;
}
public boolean equals(Object obj) {
Coordinate other = (Coordinate) obj;
return this.x == other.x && this.y == other.y;
}
public int hashCode() {
return x ^ y;
}
}
public class Solution {
private boolean dfs(char[][] board, String word, int letter, Map<Coordinate,
Boolean> used, int i, int j) {
if (letter >= word.length()) {
return true;
}
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board
[i][j] != word.charAt(letter)) {

return false;
}
used.put(new Coordinate(i, j), true);
Coordinate
Coordinate
Coordinate
Coordinate

above = new Coordinate(i, j + 1);


below = new Coordinate(i, j - 1);
left = new Coordinate(i - 1, j);
right = new Coordinate(i + 1, j);

if (!used.containsKey(above) && dfs(board, word, letter + 1, used, i, j


+ 1)) {
return true;
}
if (!used.containsKey(below) && dfs(board, word, letter + 1, used, i, j
- 1)) {
return true;
}
if (!used.containsKey(left) && dfs(board, word, letter + 1, used, i - 1,
j)) {
return true;
}
if (!used.containsKey(right) && dfs(board, word, letter + 1, used, i + 1
, j)) {
return true;
}
used.remove(new Coordinate(i, j));
return false;
}
public boolean exist(char[][] board, String word) {
if (board == null || word == null) {
throw new NullPointerException();
}
// run dfs from every position
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
Map<Coordinate, Boolean> used = new HashMap<>();
if (dfs(board, word, 0, used, i, j)) {
return true;
}
}
}
return false;
}
}
76. Given a set of distinct integers, S, return all possible subsets.
Note:
Elements in a subset must be in non-descending order.
The solution set must not contain duplicate subsets.

For example,
If S = [1,2,3], a solution is:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
public class Solution {
private boolean isBitSet(int num, int bit) {
return (num & (1 << bit)) != 0;
}
public List<List<Integer>> subsets(int[] S) {
if (S == null) {
throw new NullPointerException();
}
if (S.length > Integer.SIZE) {
throw new IllegalArgumentException();
}
Arrays.sort(S);
List<List<Integer>> ret = new ArrayList<>();
int max = (1 << S.length) - 1;
// bits of i represent which members of S to include
for (int i = 0; i <= max; i++) {
List<Integer> sol = new ArrayList<>();
for (int j = 0; j < S.length; j++) {
if (isBitSet(i, j)) {
sol.add(S[j]);
}
}
ret.add(sol);
}
return ret;
}
}
77. Given two integers n and k, return all possible combinations of k numbers ou
t of 1 ... n.
For example,
If n = 4 and k = 2, a solution is:
[

[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
public class Solution {
// idea 1: solve recursively
//
call combine on n-1, k AND then do N + (n-1, k-1)
public List<List<Integer>> combine(int n, int k) {
if (k < 0 || n < 1 || k > n) {
throw new IllegalArgumentException();
}
List<List<Integer>> ret = new ArrayList<>();
// handle base cases
if (k == 0) {
List<Integer> sol = new ArrayList<>();
ret.add(sol);
return ret;
}
// k must also now be 1 if n is 1
else if (n == 1) {
assert k == 1;
List<Integer> sol = new ArrayList<>();
sol.add(1);
ret.add(sol);
return ret;
}
// set ret to combinations using all numbers except N
if (n > k) {
ret = combine(n - 1, k);
}
// now add all ways of using N
List<List<Integer>> kMinusOne = combine(n - 1, k - 1);
for (List<Integer> list : kMinusOne) {
list.add(n);
}
// combine the lists and return
ret.addAll(kMinusOne);
return ret;
}
}
78. Given a string S and a string T, find the minimum window in S which will con
tain all the characters in T in complexity O(n).
For example,
S = "ADOBECODEBANC"
T = "ABC"

Minimum window is "BANC".


Note:
If there is no such window in S that covers all characters in T, return the emtp
y string "".
If there are multiple such windows, you are guaranteed that there will always be
only one unique minimum window in S.
public class Solution {
private Map<Character, Integer> buildHistogram(String needle, String haystac
k) {
Map<Character, Integer> histogram = new HashMap<>();
for (char c : needle.toCharArray()) {
if (histogram.containsKey(c)) {
histogram.put(c, histogram.get(c) + 1);
} else {
histogram.put(c, 1);
}
}
for (char c : haystack.toCharArray()) {
if (!histogram.containsKey(c)) {
histogram.put(c, 0);
}
}
return histogram;
}
public String minWindow(String S, String T) {
if (S == null || T == null) {
throw new NullPointerException();
}
if (S.length() == 0 || T.length() == 0) {
return new String("");
}
int bestStart;
int bestEnd;
// inclusive start; exclusive end
int start;
int end;
Map<Character, Integer> requiredCount = buildHistogram(T, S);
Map<Character, Integer> windowCount = buildHistogram("", S);
int requiredInWindow = 0;
for (end = 0; end < S.length() && requiredInWindow < T.length(); end++)
{
char c = S.charAt(end);
// update requiredInWindow
if (windowCount.get(c) < requiredCount.get(c)) {
requiredInWindow++;
}

windowCount.put(c, windowCount.get(c) + 1);


}
// no window will suffice
if (requiredInWindow < T.length()) {
return new String("");
}
for (start = 0; requiredCount.get(S.charAt(start)) < windowCount.get(S.c
harAt(start)); start++) {
windowCount.put(S.charAt(start), windowCount.get(S.charAt(start)) 1);
}
bestStart = start;
bestEnd = end;
// during each iteration we either increment both start and end, or we s
horten window somehow (try end first)
while (true) {
// try to shorten window from end
char last = S.charAt(end - 1);
if (requiredInWindow == T.length() && requiredCount.get(last) < wind
owCount.get(last)) {
end--;
bestStart = start;
bestEnd = end;
windowCount.put(last, windowCount.get(last) - 1);
continue;
}
// try to shorten window from start
char first = S.charAt(start);
if (requiredInWindow == T.length() && requiredCount.get(first) < win
dowCount.get(first)) {
start++;
bestStart = start;
bestEnd = end;
windowCount.put(first, windowCount.get(first) - 1);
continue;
}
if (end == S.length()) {
break;
}
// advance pointers
start++;
end++;
char lost = S.charAt(start - 1);
char gained = S.charAt(end - 1);
if (requiredCount.get(lost) >= windowCount.get(lost)) {
requiredInWindow--;
}
windowCount.put(lost, windowCount.get(lost) - 1);

if (requiredCount.get(gained) > windowCount.get(gained)) {


requiredInWindow++;
}
windowCount.put(gained, windowCount.get(gained) + 1);
}
return S.substring(bestStart, bestEnd);
}
}

79. Given an array with n objects colored red, white or blue, sort them so that
objects of the same color are adjacent, with the colors in the order red, white
and blue.
Here, we will use the integers 0, 1, and 2 to represent the color red, white, an
d blue respectively.
Note:
You are not suppose to use the library's sort function for this problem.
public class Solution {
// 0 0 0 0 1 1 1 1 x x x x x x x 2 2 2 2 2 2
//
a
b
c
public void sortColors(int[] A) {
if (A == null) {
throw new NullPointerException();
}
int a = 0;
int b = 0;
int c = A.length - 1;
while (b <= c) {
if (A[b] == 0) {
A[a] ^= A[b];
A[b] ^= A[a];
A[a] ^= A[b];
a++;
b++;
} else if (A[b] == 1) {
b++;
} else if (A[b] == 2) {
if (b == c) {
break;
}
A[b] ^= A[c];
A[c] ^= A[b];
A[b] ^= A[c];
c--;
} else {
throw new IllegalArgumentException();
}

}
}
}
80. Write an efficient algorithm that searches for a value in an m x n matrix. T
his matrix has the following properties:
Integers in each row are sorted from left to right.
The first integer of each row is greater than the last integer of the previous r
ow.
For example,
Consider the following matrix:
[
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]

Given target = 3, return true.

public class Solution {


private int getRowForIndex(int[][] matrix, int i) {
return i / matrix[0].length;
}
private int getColForIndex(int[][] matrix, int i) {
return i % matrix[0].length;
}
public boolean searchMatrix(int[][] matrix, int target) {
if (matrix == null) {
throw new NullPointerException();
}
if (matrix.length == 0 || matrix[0].length == 0) {
return false;
}
// smallest index which target could be at
int min = 0;
// greatest index which target could be at
int max = matrix.length * matrix[0].length - 1;
while (min < max) {
int test = (min + max) / 2;
int val = matrix[getRowForIndex(matrix, test)][getColForIndex(matrix
, test)];
if (val == target) {
return true;
} else if (val < target) {
min = test + 1;

} else {
max = test - 1;
}
}
return matrix[getRowForIndex(matrix, min)][getColForIndex(matrix, min)]
== target;
}
}

81. Given a m x n matrix, if an element is 0, set its entire row and column to 0
. Do it in place.
click to show follow up.
Follow up:
Did you use extra space?
A straight forward solution using O(mn) space is probably a bad idea.
A simple improvement uses O(m + n) space, but still not the best solution.
Could you devise a constant space solution?

public class Solution {


private static final int X = -99;
private void zeroOutRow(int[][] matrix, int row) {
for (int i = 0; i < matrix[row].length; i++) {
if (matrix[row][i] != 0) {
matrix[row][i] = X;
}
}
for (int i = 0; i < matrix[row].length; i++) {
if (matrix[row][i] == 0) {
matrix[row][i] = X;
zeroOutCol(matrix, i);
}
}
}
private void zeroOutCol(int[][] matrix, int col) {
for (int i = 0; i < matrix.length; i++) {
if (matrix[i][col] != 0) {
matrix[i][col] = X;
}
}
for (int i = 0; i < matrix.length; i++) {
if (matrix[i][col] == 0) {
matrix[i][col] = X;
zeroOutRow(matrix, i);
}
}
}
public void setZeroes(int[][] matrix) {
if (matrix == null) {

throw new NullPointerException();


}
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] == 0) {
zeroOutRow(matrix, i);
zeroOutCol(matrix, j);
}
}
}
// replace all X with 0
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] == X) {
matrix[i][j] = 0;
}
}
}
}
}
82. Given two words word1 and word2, find the minimum number of steps required
to convert word1 to word2. (each operation is counted as 1 step.)
You have the following 3 operations permitted on a word:
a) Insert a character
b) Delete a character
c) Replace a character
public class Solution {
private void helper(String word1, int pos1, String word2, int pos2, int[][]
cache) {
if (cache[pos1][pos2] != -1) {
return;
}
if (pos1 >= word1.length() || pos2 >= word2.length()) {
cache[pos1][pos2] = Math.max(word1.length() - pos1, word2.length() pos2);
return;
}
if (word1.charAt(pos1) == word2.charAt(pos2)) {
helper(word1, pos1 + 1, word2, pos2 + 1, cache);
cache[pos1][pos2] = cache[pos1 + 1][pos2 + 1];
return;
}
helper(word1, pos1 + 1, word2, pos2, cache);
helper(word1, pos1, word2, pos2 + 1, cache);
helper(word1, pos1 + 1, word2, pos2 + 1, cache);
int temp = Math.min(cache[pos1 + 1][pos2], cache[pos1][pos2 + 1]);
cache[pos1][pos2] = 1 + Math.min(temp, cache[pos1 + 1][pos2 + 1]);
}

public
//
//
//
//
//

int minDistance(String word1, String word2) {


go through longer, on match recurse
on mismatch few options:
1: delete from shorter and recurse
2: delete from longer and recurse
3: replace either and recurse

if (word1 == null || word2 == null) {


throw new NullPointerException();
}
int[][] cache = new int[word1.length() + 1][word2.length() + 1];
for (int i = 0; i < word1.length() + 1; i++) {
for (int j = 0; j < word2.length() + 1; j++) {
cache[i][j] = -1;
}
}
helper(word1, 0, word2, 0, cache);
return cache[0][0];
}
}

83. Given an absolute path for a file (Unix-style), simplify it.


For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
click to show corner cases.
Corner Cases:
Did you consider the case where
In this case, you should return
Another corner case is the path
h as "/home//foo/".
In this case, you should ignore

path = "/../"?
"/".
might contain multiple slashes '/' together, suc
redundant slashes and return "/home/foo".

public class Solution {


public String simplifyPath(String path) {
if (path == null) {
throw new NullPointerException();
}
Stack<String> dirs = new Stack<>();
int pos = 0;
// continue to deal with tokens until we run out
while (pos < path.length()) {
// ignore starting slashes
while (pos < path.length() && path.charAt(pos) == '/') {
pos++;
}
// if we hit end of string, break (possibly on last token)

if (pos >= path.length()) {


break;
}
// find endPos of token
int endPos = pos + 1;
while(endPos < path.length() && path.charAt(endPos) != '/') {
endPos++;
}
String token = path.substring(pos, endPos);
if (token.equals(".")) {
pos = endPos;
continue;
} else if (token.equals("..")) {
if (!dirs.isEmpty()) {
dirs.pop();
}
} else {
dirs.push(token);
}
pos = endPos;
}
if (dirs.isEmpty()) {
return "/";
}
// build simplified path from the stack
StringBuilder ret = new StringBuilder();
while (!dirs.isEmpty()) {
String dir = dirs.pop();
ret.insert(0, "/" + dir);
}
return ret.toString();
}
}

84. You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you c
limb to the top?
public class Solution {
public int climbStairs(int n) {
if (n < 0) {
throw new IllegalArgumentException();
} else if (n == 0) {
return 1;
} else if (n == 1) {
return 1;
} else if (n == 2) {

return 2;
}
int upTwoWays = 1;
int upOneWays = 2;
int onStep = 3;
while (onStep <= n) {
int upZeroWays = upOneWays + upTwoWays;
upTwoWays = upOneWays;
upOneWays = upZeroWays;
onStep++;
}
return upOneWays;
}
}
85. Implement int sqrt(int x).
Compute and return the square root of x.
public class Solution {
// binary search
public int sqrt(int x) {
if (x < 0) {
throw new IllegalArgumentException();
} else if (x == 0) {
return 0;
} else if (x == 1) {
return 1;
}
// greatest number known to be <= sqrt(x)
int min = 1;
// smallest number known to be >= sqrt(x)
int max = x;
while (max - min > 1) {
int test = max / 2 + min / 2 + (max % 2 + min % 2 == 2 ? 1 : 0);
int res = x / test;
if (res >= test) {
min = test;
} else {
max = test;
}
}
return min;
}
}
86. Given an array of words and a length L, format the text such that each line
has exactly L characters and is fully (left and right) justified.

You should pack your words in a greedy approach; that is, pack as many words as
you can in each line. Pad extra spaces ' ' when necessary so that each line has
exactly L characters.
Extra spaces between words should be distributed as evenly as possible. If the n
umber of spaces on a line do not divide evenly between words, the empty slots on
the left will be assigned more spaces than the slots on the right.
For the last line of text, it should be left justified and no extra space is ins
erted between words.
For example,
words: ["This", "is", "an", "example", "of", "text", "justification."]
L: 16.
Return the formatted lines as:
[
"This
is
an",
"example of text",
"justification. "
]
Note: Each word is guaranteed not to exceed L in length.
click to show corner cases.
Corner Cases:
A line other than the last line might contain only one word. What should you do
in this case?
In this case, that line should be left-justified.
public class Solution {
public List<String> fullJustify(String[] words, int L) {
if (words == null) {
throw new NullPointerException();
}
List<String> ret = new ArrayList<>();
int wordsProcessed = 0;
while (wordsProcessed < words.length) {
StringBuffer nextLine = new StringBuffer();
int wordsOnLine = 0;
int minLength = 0;
while (wordsProcessed + wordsOnLine < words.length) {
String nextWord = words[wordsProcessed + wordsOnLine];
int spacesRequired = wordsOnLine == 0 ? 0 : 1;
if (minLength + spacesRequired + nextWord.length() <= L) {
wordsOnLine++;
minLength += spacesRequired + nextWord.length();
} else {
break;
}
}
if (wordsOnLine == 0) {

throw new IllegalArgumentException();


}
// lines with one word and last line should be left-justified
if (wordsOnLine == 1 || wordsProcessed + wordsOnLine == words.length
) {
nextLine.append(words[wordsProcessed]);
for (int i = 1; i < wordsOnLine; i++) {
nextLine.append(" ");
nextLine.append(words[wordsProcessed + i]);
}
// append spaces to finish line
for (int i = minLength; i < L; i++) {
nextLine.append(" ");
}
}
// center justify
else {
int spacesLeft = L - (minLength - (wordsOnLine - 1));
int gapsLeft = wordsOnLine - 1;
nextLine.append(words[wordsProcessed]);
for (int i = 1; i < wordsOnLine; i++) {
// calculate spaces to append
int spacesToAppend = spacesLeft / gapsLeft;
if (spacesLeft % gapsLeft != 0) {
spacesToAppend++;
}
for (int j = 0; j < spacesToAppend; j++) {
nextLine.append(" ");
}
nextLine.append(words[wordsProcessed + i]);
spacesLeft -= spacesToAppend;
gapsLeft--;
}
}
wordsProcessed += wordsOnLine;
ret.add(nextLine.toString());
}
return ret;
}
}
87. Given a non-negative number represented as an array of digits, plus one to t
he number.
The digits are stored such that the most significant digit is at the head of the
list.

public class Solution {


public int[] plusOne(int[] digits) {
int[] ret = Arrays.copyOf(digits, digits.length);
int i;
for (i = ret.length - 1; i >= 0; i--) {
if (ret[i] == 9) {
ret[i] = 0;
} else {
ret[i]++;
break;
}
}
if (i == -1) {
int[] newRet = new int[ret.length + 1];
newRet[0] = 1;
for (int j = 1; j < newRet.length; j++) {
newRet[j] = ret[j - 1];
}
ret = newRet;
}
return ret;
}
}
88. Validate if a given string is numeric.
Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
Note: It is intended for the problem statement to be ambiguous.
You should gather all requirements up front before implementing one.
public class Solution {
// test from end to beginning
// optional 1 or more spaces
// mandatory 1 or more digits(OR decimal point but then there has to be some
thing before it)
// optional e with 1 or more digits preceeding
// optional decimal point
// optional 1 or more digits
// optional + or // optional 1 or more spaces
public boolean isNumber(String s) {
if (s == null) {
throw new NullPointerException();
}
boolean foundRealFuckingDigit = false;
if (s.length() == 0) {
return false;

}
int pos = s.length() - 1;
while (pos >= 0 && Character.isSpaceChar(s.charAt(pos))) {
pos--;
}
// special case
if (pos >= 0 && s.charAt(pos) == '.') {
pos--;
if (pos < 0 || !Character.isDigit(s.charAt(pos))) {
return false;
}
while (pos >= 0 && Character.isDigit(s.charAt(pos))) {
foundRealFuckingDigit = true;
pos--;
}
if (pos >= 0 && (s.charAt(pos) == '+' || s.charAt(pos) == '-')) {
pos--;
}
while (pos >= 0 && Character.isSpaceChar(s.charAt(pos))) {
pos--;
}
return pos < 0 && foundRealFuckingDigit;
}
if (pos < 0 || !Character.isDigit(s.charAt(pos))) {
return false;
}
while (pos >= 0 && Character.isDigit(s.charAt(pos))) {
foundRealFuckingDigit = true;
pos--;
}
if (pos < 0) {
return true;
}
// handle sign
if (s.charAt(pos) == '+' || s.charAt(pos) == '-') {
pos--;
if (foundRealFuckingDigit) {
boolean foundSpace = false;
while (pos >= 0 && Character.isSpaceChar(s.charAt(pos))) {
foundSpace = true;
pos--;
}
if (pos < 0) {
return true;
} else if (foundSpace) {
return false;
}

} else {
return false;
}
if (s.charAt(pos) != 'e') {
return false;
}
}
if (s.charAt(pos) == 'e') {
pos--;
foundRealFuckingDigit = false;
if (pos < 0) {
return false;
}
if (s.charAt(pos) != '.') {
if (!Character.isDigit(s.charAt(pos))) {
return false;
}
while(pos >= 0 && Character.isDigit(s.charAt(pos))) {
foundRealFuckingDigit = true;
pos--;
}
if (pos < 0) {
return true;
}
}
}
if (s.charAt(pos) == '.') {
pos--;
}
while (pos >= 0 && Character.isDigit(s.charAt(pos))) {
foundRealFuckingDigit = true;
pos--;
}
if (pos >= 0 && (s.charAt(pos) == '+' || s.charAt(pos) == '-')) {
pos--;
}
while (pos >= 0 && Character.isSpaceChar(s.charAt(pos))) {
pos--;
}
return pos < 0 && foundRealFuckingDigit;
}
}
89. Given two binary strings, return their sum (also a binary string).
For example,
a = "11"
b = "1"

Return "100".
public class Solution {
public String addBinary(String a, String b) {
if (a == null || b == null) {
throw new NullPointerException();
}
// make a the shorter String for convenience
if (a.length() > b.length()) {
String temp = a;
a = b;
b = temp;
}
int[] sum = new int[b.length()];
int carry = 0;
for (int order = 0; order < b.length(); order++) {
int aVal = order < a.length() ? (a.charAt(a.length() - 1 - order) '0') : 0;
sum[b.length() - 1 - order] = aVal + (b.charAt(b.length() - 1 - orde
r) - '0') + carry;
carry = sum[b.length() - 1 - order] / 2;
sum[b.length() - 1 - order] %= 2;
}
char[] sumChar = new char[b.length()];
for (int i = 0; i < b.length(); i++) {
sumChar[i] = (char) ('0' + sum[i]);
}
return carry == 0 ? new String(sumChar) : "1" + new String(sumChar);
}
}
90. Merge two sorted linked lists and return it as a new list.
The new list should be made by splicing together the nodes of the first two lis
ts.
/**
* Definition for singly-linked list.
* public class ListNode {
*
int val;
*
ListNode next;
*
ListNode(int x) {
*
val = x;
*
next = null;
*
}
* }
*/
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode sentinel = new ListNode(0);
ListNode tail = sentinel;

while (l1 != null && l2 != null) {


if (l1.val < l2.val) {
tail.next = l1;
tail = tail.next;
l1 = l1.next;
} else {
tail.next = l2;
tail = tail.next;
l2 = l2.next;
}
}
while (l1 != null) {
tail.next = l1;
tail = tail.next;
l1 = l1.next;
}
while (l2 != null) {
tail.next = l2;
tail = tail.next;
l2 = l2.next;
}
return sentinel.next;
}
}
91. Given a m x n grid filled with non-negative numbers, find a path from top le
ft to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
public class Solution {
public int minPathSum(int[][] grid) {
if (grid == null) {
throw new NullPointerException();
}
int rows = grid.length;
if (rows == 0) {
throw new IllegalArgumentException();
}
int cols = grid[0].length;
if (cols == 0) {
throw new IllegalArgumentException();
}
int[] minCost = new int[cols];
for (int i = rows - 1; i >= 0; i--) {
if (grid[i].length != cols) {
throw new IllegalArgumentException();
}
for (int j = cols - 1; j >= 0; j--) {

if (j == cols - 1) {
minCost[j] = grid[i][j] + minCost[j];
} else if (i == rows - 1) {
minCost[j] = grid[i][j] + minCost[j + 1];
} else {
minCost[j] = grid[i][j] + Math.min(minCost[j], minCost[j + 1
]);
}
}
}
return minCost[0];
}
}
92. Follow up for "Unique Paths":
Now consider if some obstacles are added to the grids. How many unique paths wou
ld there be?
An obstacle and empty space is marked as 1 and 0 respectively in the grid.
For example,
There is one obstacle in the middle of a 3x3 grid as illustrated below.
[
[0,0,0],
[0,1,0],
[0,0,0]
]
The total number of unique paths is 2.
Note: m and n will be at most 100.
public class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
if (obstacleGrid == null) {
throw new NullPointerException();
}
int rows = obstacleGrid.length;
if (rows == 0) {
return 0;
}
int cols = obstacleGrid[0].length;
if (cols == 0) {
return 0;
}
// test simple cases
if (obstacleGrid[0][0] == 1) {
return 0;
} else if (obstacleGrid[rows - 1][cols - 1] == 1) {
return 0;
}

int[] numPaths = new int[cols];


// do final row
numPaths[cols - 1] = 1;
for (int col = cols - 2; col >= 0; col--) {
numPaths[col] = obstacleGrid[rows - 1][col] == 1 ? 0 : numPaths[col
+ 1];
}
// do all other rows
for (int row = rows - 2; row >= 0; row--) {
// do last col
numPaths[cols - 1] = obstacleGrid[row][cols - 1] == 1 ? 0 : numPaths
[cols - 1];
// do other cols
for (int col = cols - 2; col >= 0; col--) {
numPaths[col] = obstacleGrid[row][col] == 1 ? 0 : (numPaths[col
+ 1] + numPaths[col]);
}
}
return numPaths[0];
}
}
93. A robot is located at the top-left corner of a m x n grid (marked 'Start' in
the diagram below).
The robot can only move either down or right at any point in time. The robot is
trying to reach the bottom-right corner of the grid (marked 'Finish' in the diag
ram below).
How many possible unique paths are there?
http://4.bp.blogspot.com/_UElib2WLeDE/TNJf8VtC2VI/AAAAAAAACXU/UyUa-9LKp4E/s400/r
obot_maze.png
Above is a 3 x 7 grid. How many possible unique paths are there?
Note: m and n will be at most 100.
public class Solution {
private double fact(int num) {
double ret = 1;
for (int i = 2; i <= num; i++) {
ret *= i;
}
return ret;
}
// m rows, n columns
public int uniquePaths(int m, int n) {
if (m < 1 || m > 100) {
throw new IllegalArgumentException();

} else if (n < 1 || n > 100) {


throw new IllegalArgumentException();
}
//
//
//
//

robot must move to the right m - 1 times


robot must move down n -1 times
# of unique paths is choose m -1 from (m + n - 2)
= (m + n - 2)! / (m - 1)! (n - 1)!

double
ret /=
ret /=
return
}
}

ret = fact(m + n - 2);


fact(m - 1);
fact(n - 1);
(int) Math.round(ret);

Potrebbero piacerti anche