Recursion:
public int minDepth(TreeNode root) {
if (root == null) return 0;
if (root.left == null && root.right == null) {
return 1;
}
else if (root.left != null && root.right != null) {
return 1+Math.min(minDepth(root.left), minDepth(root.right));
}
else if (root.left == null && root.right != null) {
return 1+minDepth(root.right);
} else {
return 1+minDepth(root.left);
}
}
Non-Recursion:
Why we use this method. Sometimes the tree is not balanced. This way will save lots of time. The worst of time complexity is O(n).
public int minDepth(TreeNode root) {
if (root == null) return 0;
Queue<TreeNode> nodeQueue = new LinkedList<TreeNode>();
Queue<Integer> intQueue = new LinkedList<Integer>();
nodeQueue.add(root);
intQueue.add(1);
while (!nodeQueue.isEmpty()) {
TreeNode currNode = nodeQueue.poll();
int currDepth = intQueue.poll();
if (currNode.left != null) {
nodeQueue.add(currNode.left);
intQueue.add(currDepth+1);
}
if (currNode.right != null) {
nodeQueue.add(currNode.right);
intQueue.add(currDepth+1);
}
if (currNode.right == null && currNode.left == null) {
return currDepth;
}
}
return -1;//Should never reach here.
}
Tuesday, October 28, 2014
Path Sum LeetCode
Recursion:
public boolean hasPathSum(TreeNode root, int sum) {
// Note: The Solution object is instantiated only once and is reused by each test case.
if (root == null) return false;
if (root.left == null && root.right == null && sum == root.val) {
return true;
} else {
return hasPathSum(root.left, sum-root.val) || hasPathSum(root.right, sum-root.val);
}
}
Non-recursion:
public boolean hasPathSum(TreeNode root, int sum) {
// Note: The Solution object is instantiated only once and is reused by each test case.
if (root==null) return false;
Queue<TreeNode> nodeQueue = new LinkedList<TreeNode>();
Queue<Integer> intQueue = new LinkedList<Integer>();
nodeQueue.add(root);
intQueue.add(root.val);
while (!nodeQueue.isEmpty()) {
TreeNode currNode = nodeQueue.poll();
int currVal = intQueue.poll();
if (currNode.left == null && currNode.right == null && sum == currVal) {
return true;
}
if (currNode.left != null) {
nodeQueue.add(currNode.left);
intQueue.add(currVal + currNode.left.val);
}
if (currNode.right != null) {
nodeQueue.add(currNode.right);
intQueue.add(currVal + currNode.right.val);
}
}
return false;
}
public boolean hasPathSum(TreeNode root, int sum) {
// Note: The Solution object is instantiated only once and is reused by each test case.
if (root == null) return false;
if (root.left == null && root.right == null && sum == root.val) {
return true;
} else {
return hasPathSum(root.left, sum-root.val) || hasPathSum(root.right, sum-root.val);
}
}
Non-recursion:
public boolean hasPathSum(TreeNode root, int sum) {
// Note: The Solution object is instantiated only once and is reused by each test case.
if (root==null) return false;
Queue<TreeNode> nodeQueue = new LinkedList<TreeNode>();
Queue<Integer> intQueue = new LinkedList<Integer>();
nodeQueue.add(root);
intQueue.add(root.val);
while (!nodeQueue.isEmpty()) {
TreeNode currNode = nodeQueue.poll();
int currVal = intQueue.poll();
if (currNode.left == null && currNode.right == null && sum == currVal) {
return true;
}
if (currNode.left != null) {
nodeQueue.add(currNode.left);
intQueue.add(currVal + currNode.left.val);
}
if (currNode.right != null) {
nodeQueue.add(currNode.right);
intQueue.add(currVal + currNode.right.val);
}
}
return false;
}
Pascal's Triangle LeetCode
Check Pascal's Triangle
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (numRows < 1) return result;
if (numRows == 1) {
List<Integer> currList = new ArrayList<Integer>();
currList.add(1);
result.add(currList);
return result;
}
List<List<Integer>> lastResult = generate(numRows-1);
result.addAll(lastResult);
List<Integer> lastList = lastResult.get(lastResult.size() - 1);
List<Integer> newList = new ArrayList<Integer>();
newList.add(1);
for (int i=0; i<lastList.size()-1; i++) {
newList.add(lastList.get(i) + lastList.get(i+1));
}
newList.add(1);
result.add(newList);
return result;
}
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (numRows < 1) return result;
if (numRows == 1) {
List<Integer> currList = new ArrayList<Integer>();
currList.add(1);
result.add(currList);
return result;
}
List<List<Integer>> lastResult = generate(numRows-1);
result.addAll(lastResult);
List<Integer> lastList = lastResult.get(lastResult.size() - 1);
List<Integer> newList = new ArrayList<Integer>();
newList.add(1);
for (int i=0; i<lastList.size()-1; i++) {
newList.add(lastList.get(i) + lastList.get(i+1));
}
newList.add(1);
result.add(newList);
return result;
}
Pascal's Triangle II Leetcode
Trivial solution without considering space
public List<Integer> getRow(int rowIndex) {
List<Integer> result = new ArrayList<Integer>();
if (rowIndex == 0) {
result.add(1);
return result;
}
List<Integer> currList = getRow(rowIndex - 1);
List<Integer> newList = new ArrayList<Integer>();
newList.add(1);
for (int i = 0; i < currList.size() - 1; i++) {
newList.add(currList.get(i) + currList.get(i+1));
}
newList.add(1);
return newList;
}
Consider about the space.
Collections.nCopies(n,0) is a smart way to initialize the arraylist as zero.
public List<Integer> getRow(int rowIndex) {
List<Integer> result = new ArrayList<Integer>(Collections.nCopies(rowIndex+1,0));
result.set(0,1);
for (int i=0; i<=rowIndex; i++) {
result.set(i,1);
for (int j=i-1; j>0; j--) {
result.set(j, result.get(j)+result.get(j-1));
}
}
return result;
}
public List<Integer> getRow(int rowIndex) {
List<Integer> result = new ArrayList<Integer>();
if (rowIndex == 0) {
result.add(1);
return result;
}
List<Integer> currList = getRow(rowIndex - 1);
List<Integer> newList = new ArrayList<Integer>();
newList.add(1);
for (int i = 0; i < currList.size() - 1; i++) {
newList.add(currList.get(i) + currList.get(i+1));
}
newList.add(1);
return newList;
}
Consider about the space.
Collections.nCopies(n,0) is a smart way to initialize the arraylist as zero.
public List<Integer> getRow(int rowIndex) {
List<Integer> result = new ArrayList<Integer>(Collections.nCopies(rowIndex+1,0));
result.set(0,1);
for (int i=0; i<=rowIndex; i++) {
result.set(i,1);
for (int j=i-1; j>0; j--) {
result.set(j, result.get(j)+result.get(j-1));
}
}
return result;
}
Wednesday, October 22, 2014
Symmetric Tree LeetCode
Recursively:
public class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return isSymmetric(root.left, root.right);
}
private boolean isSymmetric(TreeNode left, TreeNode right) {
if (left == null && right == null) return true;
if (left == null || right == null) return false;
if (left.val != right.val ) return false;
return isSymmetric(left.left, right.right) && isSymmetric(left.right, right.left);
}
}
Iteratively:
public boolean isSymmetric(TreeNode root) {
if (root == null || root.left == null && root.right == null) return true;
Queue<TreeNode> lq = new LinkedList<TreeNode>();
Queue<TreeNode> rq = new LinkedList<TreeNode>();
lq.add(root.left);
rq.add(root.right);
TreeNode leftTreeNode = null;
TreeNode rightTreeNode = null;
while (lq.isEmpty() == false && rq.isEmpty() == false) {
leftTreeNode = lq.poll();
rightTreeNode = rq.poll();
if (leftTreeNode == null && rightTreeNode == null) {
continue;
}
if ((leftTreeNode == null && rightTreeNode != null )|| (leftTreeNode != null && rightTreeNode == null)) {
return false;
}
if (leftTreeNode.val != rightTreeNode.val) {
return false;
}
lq.add(leftTreeNode.left);
lq.add(leftTreeNode.right);
rq.add(rightTreeNode.right);
rq.add(rightTreeNode.left);
}
return (lq.isEmpty()&&rq.isEmpty());
}
public class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return isSymmetric(root.left, root.right);
}
private boolean isSymmetric(TreeNode left, TreeNode right) {
if (left == null && right == null) return true;
if (left == null || right == null) return false;
if (left.val != right.val ) return false;
return isSymmetric(left.left, right.right) && isSymmetric(left.right, right.left);
}
}
Iteratively:
public boolean isSymmetric(TreeNode root) {
if (root == null || root.left == null && root.right == null) return true;
Queue<TreeNode> lq = new LinkedList<TreeNode>();
Queue<TreeNode> rq = new LinkedList<TreeNode>();
lq.add(root.left);
rq.add(root.right);
TreeNode leftTreeNode = null;
TreeNode rightTreeNode = null;
while (lq.isEmpty() == false && rq.isEmpty() == false) {
leftTreeNode = lq.poll();
rightTreeNode = rq.poll();
if (leftTreeNode == null && rightTreeNode == null) {
continue;
}
if ((leftTreeNode == null && rightTreeNode != null )|| (leftTreeNode != null && rightTreeNode == null)) {
return false;
}
if (leftTreeNode.val != rightTreeNode.val) {
return false;
}
lq.add(leftTreeNode.left);
lq.add(leftTreeNode.right);
rq.add(rightTreeNode.right);
rq.add(rightTreeNode.left);
}
return (lq.isEmpty()&&rq.isEmpty());
}
Wednesday, October 1, 2014
LeetCode Maximum Subarray
General solution.
public int maxSubArray(int[] A) {
// Note: The Solution object is instantiated only once and is reused by each test case.
int runningSum = 0;
int totalSum = A[0];
for (int i = 0; i < A.length; i++) {
runningSum += A[i];
if (runningSum > 0) {
totalSum = Math.max(runningSum, totalSum);
} else {
totalSum = Math.max(totalSum, A[i]);
runningSum = 0;
}
}
return totalSum;
}
DP
Memory optimization
public int maxSubArray(int[] A) {
int maxEndingHere = A[0], maxSoFar = A[0];
for (int i=1; i<A.length; i++) {
maxEndingHere = Math.max(maxEndingHere + A[i], A[i]);
maxSoFar = Math.max(maxEndingHere, maxSoFar);
}
return maxSoFar;
}
D&C
Implement the binary search everywhere.
public int maxSubArray(int[] A) {
// Note: The Solution object is instantiated only once and is reused by each test case.
int maxSum = Integer.MIN_VALUE;
return findMaxSub(A, 0, A.length - 1, maxSum);
}
//Recursive to find max sum
//may appear on the left, right or crossing the mid point
private int findMaxSub(int[] A, int left, int right, int maxSum) {
if (left > right) return Integer.MIN_VALUE;
//Get Max sub by recursive ways
int mid = (left + right)/2;
int leftMax = findMaxSub(A, left, mid-1, maxSum);
int rightMax = findMaxSub(A, mid+1, right, maxSum);
maxSum = Math.max(maxSum, Math.max(leftMax, rightMax));
//GEt Max sum by crossing mid
int lSum = 0;
int midLeftMax = 0;
for (int i = mid-1; i>=left; i--) {
lSum = lSum + A[i];
if (lSum > midLeftMax) midLeftMax = lSum;
}
int rSum = 0;
int midRightMax = 0;
for (int i = mid+1; i<=right; i++) {
rSum = rSum + A[i];
if (rSum > midRightMax) midRightMax = rSum;
}
maxSum = Math.max(maxSum, midLeftMax + midRightMax + A[mid]);
return maxSum;
}
public int maxSubArray(int[] A) {
// Note: The Solution object is instantiated only once and is reused by each test case.
int runningSum = 0;
int totalSum = A[0];
for (int i = 0; i < A.length; i++) {
runningSum += A[i];
if (runningSum > 0) {
totalSum = Math.max(runningSum, totalSum);
} else {
totalSum = Math.max(totalSum, A[i]);
runningSum = 0;
}
}
return totalSum;
}
DP
Memory optimization
public int maxSubArray(int[] A) {
int maxEndingHere = A[0], maxSoFar = A[0];
for (int i=1; i<A.length; i++) {
maxEndingHere = Math.max(maxEndingHere + A[i], A[i]);
maxSoFar = Math.max(maxEndingHere, maxSoFar);
}
return maxSoFar;
}
D&C
Implement the binary search everywhere.
public int maxSubArray(int[] A) {
// Note: The Solution object is instantiated only once and is reused by each test case.
int maxSum = Integer.MIN_VALUE;
return findMaxSub(A, 0, A.length - 1, maxSum);
}
//Recursive to find max sum
//may appear on the left, right or crossing the mid point
private int findMaxSub(int[] A, int left, int right, int maxSum) {
if (left > right) return Integer.MIN_VALUE;
//Get Max sub by recursive ways
int mid = (left + right)/2;
int leftMax = findMaxSub(A, left, mid-1, maxSum);
int rightMax = findMaxSub(A, mid+1, right, maxSum);
maxSum = Math.max(maxSum, Math.max(leftMax, rightMax));
//GEt Max sum by crossing mid
int lSum = 0;
int midLeftMax = 0;
for (int i = mid-1; i>=left; i--) {
lSum = lSum + A[i];
if (lSum > midLeftMax) midLeftMax = lSum;
}
int rSum = 0;
int midRightMax = 0;
for (int i = mid+1; i<=right; i++) {
rSum = rSum + A[i];
if (rSum > midRightMax) midRightMax = rSum;
}
maxSum = Math.max(maxSum, midLeftMax + midRightMax + A[mid]);
return maxSum;
}
Subscribe to:
Posts (Atom)