Leetcode

  • Uploaded by: Pratik Patel
  • 0
  • 0
  • March 2021
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Leetcode as PDF for free.

More details

  • Words: 19,123
  • Pages: 96
Loading documents preview...
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 stack = new Stack(); 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 map; public LRUCache(int capacity) { if (capacity < 1) { throw new IllegalArgumentException(); } this.capacity = capacity; this.map = new HashMap(); } 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 postorderTraversal(TreeNode root) { List 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 preorderTraversal(TreeNode root) { List 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 queue = new LinkedList(); Stack stack = new Stack(); 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>> subproblems, boolean[] alreadyTried) { if (alreadyTried[index]) { return; } List> 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> 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>> subproblems = new ArrayList>>

(); for (int i = 0; i < s.length(); i++) { subproblems.add(new ArrayList>()); } boolean[] alreadyTried = new boolean[s.length()]; wordBreakHelper(s, 0, dict, subproblems, alreadyTried); // generate ret List> 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 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 neighbors; * UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList(); } * }; */ public class Solution { private void cloneHelper(UndirectedGraphNode node, Map
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 cloned = new HashMap(); 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>> 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> firstPartitionings = cache.get(j); List> 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>> for which get(i) gives a List> // 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> partition(String s) { if (s == null) { throw new NullPointerException(); } // inialize caching data structure List>> partitioningsOfFirstI = new ArrayList<>(); for (int i = 0; i <= s.length(); i++) { partitioningsOfFirstI.add(new ArrayList>()); } 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 nextI = new LinkedList<>(); Queue 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 counts = new HashMap();

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> 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>(); } Map<String, List>> shortestPaths = new HashMap<>(); shortestPaths.put(start, new ArrayList>()); shortestPaths.get(start).add(new ArrayList<String>()); shortestPaths.get(start).get(0).add(start); Queue<String> q = new LinkedList<>(); q.add(start); List> ret = new ArrayList>(); 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> solutions = new ArrayList>(); 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> 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> triangle) { if (triangle == null) { throw new NullPointerException(); } else if (triangle.size() == 0) { throw new IllegalArgumentException(); } List minSum = new ArrayList(triangle.get(triangle.size () - 1)); for (int nextRowToSolve = triangle.size() - 2; nextRowToSolve >= 0; next RowToSolve--) { List 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 getNextRow(List prevRow) { List 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 getRow(int rowIndex) { if (rowIndex < 0) { throw new IllegalArgumentException(); } List currentRow = new ArrayList(); 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 getNextRow(List prevRow) { List 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> generate(int numRows) { if (numRows < 0) { throw new IllegalArgumentException(); } List> ret = new ArrayList>(); if (numRows == 0) { return ret; } List firstRow = new ArrayList(); firstRow.add(1); ret.add(firstRow); List 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 currentPath , List> goodPaths) { if (node == null) { return; } else if (node.left == null && node.right == null) { if (node.val == sum) {

List sol = new ArrayList(currentPath); sol.add(node.val); goodPaths.add(sol); } return; } List newCurrentPath = new ArrayList(currentPath); newCurrentPath.add(node.val); int newSum = sum - node.val; pathSumHelper(node.left, newSum, newCurrentPath, goodPaths); pathSumHelper(node.right, newSum, newCurrentPath, goodPaths); } public List> pathSum(TreeNode root, int sum) { List currentPath = new ArrayList(); List> ret = new ArrayList>(); 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> levelOrderBottom(TreeNode root) { LinkedList> levels = new LinkedList>(); List currentLevel = new ArrayList(); if (root != null) { currentLevel.add(root); } while (!currentLevel.isEmpty()) { levels.addFirst(currentLevel); List nextLevel = new ArrayList(); 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> ret = new ArrayList>(); for (List nodes : levels) { List retLevel = new ArrayList(); 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> zigzagLevelOrder(TreeNode root) { List> ret = new ArrayList<>(); if (root == null) { return ret; } boolean goingRight = true; Stack currentLevel = new Stack<>(); currentLevel.push(root); while (!currentLevel.isEmpty()) { List currentLevelInts = new ArrayList<>(); ret.add(currentLevelInts); Stack 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> levelOrder(TreeNode root) { List> ret = new ArrayList>(); if (root == null) { return ret; } List currentLevel = new ArrayList(); currentLevel.add(root); while (!currentLevel.isEmpty()) { List ints = new ArrayList(); ret.add(ints); List nextLevel = new ArrayList(); 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

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> 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> caches = new ArrayList<Map >(); for (int i = 0; i <= s1.length(); i++) { caches.add(new HashMap()); } 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

/ 3

/

2 /

2 / \

/ 1

1

1 \ 3

2

\

\ 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 generateTrees(int n) { // cache.get(i) = list of all trees of size i List> cache = new ArrayList>(); for (int i = 0; i <= n; i++) { cache.add(new ArrayList()); } // 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

/ 2

3

/ / 1

2 / \

/ 1

1 \

1 \ 3

2 \

2

public class Solution {

3

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 inorderTraversal(TreeNode root) { List ret = new ArrayList<>(); if (root == null) { return ret; } Stack 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> subsetsWithDup(int[] num) { if (num == null) { throw new NullPointerException(); } List> 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 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 grayCode(int n) { if (n < 0) { throw new IllegalArgumentException(); } List 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 counts = new HashMap(); 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 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 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 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 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> subsets(int[] S) { if (S == null) { throw new NullPointerException(); } if (S.length > Integer.SIZE) { throw new IllegalArgumentException(); } Arrays.sort(S); List> 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 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> combine(int n, int k) { if (k < 0 || n < 1 || k > n) { throw new IllegalArgumentException(); } List> ret = new ArrayList<>(); // handle base cases if (k == 0) { List 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 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> kMinusOne = combine(n - 1, k - 1); for (List 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 buildHistogram(String needle, String haystac k) { Map 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 requiredCount = buildHistogram(T, S); Map 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);

Related Documents

Leetcode
March 2021 0

More Documents from "Akshit Sharma"

Leetcode
March 2021 0
Labour Law 2 Proj
February 2021 1
January 2021 1
Arbitrage
February 2021 0