/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var zigzagLevelOrder = function(root) {
var result = [];
if (root == null) {
return result;
}
var queue = [];
queue.push(root);
var isOdd = true;
while (queue.length != 0) {
var size = queue.length;
var level = [];
for (var i = 0; i < size; i++) {
var node = queue.shift();
if (node.left != null) {
queue.push(node.left);
}
if (node.right != null) {
queue.push(node.right);
}
level.push(node.val);
}
if (isOdd == false) {
level.reverse();
}
result.push(level);
isOdd = !isOdd;
}
return result;
};
2016年8月23日星期二
[LeetCode]103. Binary Tree Zigzag Level Order Traversal
[LeetCode]107. Binary Tree Level Order Traversal II
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrderBottom = function(root) {
var result = [];
if (root == null) {
return result;
}
var queue = [];
queue.push(root);
while (queue.length != 0) {
var size = queue.length;
var level = [];
for (var i = 0; i < size; i++) {
var node = queue.shift();
if (node.left != null) queue.push(node.left);
if (node.right != null) queue.push(node.right);
level.push(node.val);
}
result.push(level);
}
return result.reverse();
};
[LeetCode]102. Binary Tree Level Order Traversal
A
/ \
B C
/ \ \
D E F
(1) 2 queues
Q1: A
Q2: BC
Q1: DEF
Q2: [N]
Q1: [N]
(2) 1 queue + dummy node
Q: A#BC#DEF#
(3) 1 queue + queue.size
* Same if it's not binary tree
/ \
B C
/ \ \
D E F
(1) 2 queues
Q1: A
Q2: BC
Q1: DEF
Q2: [N]
Q1: [N]
(2) 1 queue + dummy node
Q: A#BC#DEF#
(3) 1 queue + queue.size
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) {
return result;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while (queue.size() != 0) {
int size = queue.size();
List<Integer> level = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
level.add(node.val);
}
result.add(level);
}
return result;
}
}
* Same if it's not binary tree
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class LevelOrder {
static class TreeNode {
int val;
List<TreeNode> children;
public TreeNode(int val, TreeNode...nodes) {
this.val = val;
this.children = new LinkedList<TreeNode>();
for (TreeNode node : nodes) {
this.children.add(node);
}
}
public int getVal() {
return val;
}
public void setVal(int val) {
this.val = val;
}
public List<TreeNode> getChildren() {
return children;
}
public void setChildren(List<TreeNode> children) {
this.children = children;
}
}
public static List<List<Integer>> levelOrderTraversal(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) {
return result;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while(queue.size() != 0) {
int size = queue.size();
List<Integer> level = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
for (TreeNode child : node.getChildren()) {
queue.offer(child);
}
level.add(node.val);
}
result.add(level);
}
return result;
}
// 1
// / | \
// 2 3 4
// /|\ | |
// 5 6 7 8 9
public static void main(String[] args) {
TreeNode root = new TreeNode(1, new TreeNode(2, new TreeNode(5), new TreeNode(6), new TreeNode(7)), new TreeNode(3, new TreeNode(8)), new TreeNode(4, new TreeNode(9)));
List<List<Integer>> result = levelOrderTraversal(root);
for (List<Integer> list : result) {
for (Integer i : list) {
System.out.print(i);
System.out.print(' ');
}
System.out.println();
}
}
}
[LeetCode]#388 Longest Absolute File Path
public class Solution {
public int lengthLongestPath(String input) {
if (input == null || input.length() == 0 || !input.contains(".")) {
return 0;
}
String[] list = input.split("\n");
Deque<Integer> stack = new ArrayDeque();
int curLength = 0;
int maxLength = -1;
for (String s : list) {
int tabs = 0;
while (s.charAt(tabs) == '\t') {
tabs++;
}
while (tabs < stack.size()) {
curLength -= stack.pop();
}
s = s.substring(tabs);
if (s.contains(".")) {
maxLength = Math.max(maxLength, curLength + s.length());
} else {
curLength += s.length() + 1;
stack.push(s.length() + 1);
}
}
return maxLength;
}
}
[LeetCode]#386 Lexicographical Numbers
* Java comparator - O(nlogn) Time Limit Exceeded
*O(n) Solution
public class Solution {
public List<Integer> lexicalOrder(int n) {
List<Integer> result = new ArrayList<Integer>();
for (int i = 1; i <= n; i++) {
result.add(i);
}
Collections.sort(result, new Comparator<Integer>(){
@Override
public int compare(Integer i1, Integer i2) {
return (Integer.toString(i1)).compareTo(Integer.toString(i2));
}
});
return result;
}
}
*O(n) Solution
public class Solution {
public List<Integer> lexicalOrder(int n) {
List<Integer> result = new ArrayList<Integer>();
if (n <= 0) {
return result;
}
int tmp = 1;
for (int i = 1; i <= n; i++) {
result.add(tmp);
if (tmp * 10 <= n) {
tmp *= 10;
} else if (tmp + 1 <= n && tmp % 10 != 9) {
tmp += 1;
} else if (tmp % 10 != 9) {
tmp = tmp / 10 + 1;
} else {
tmp++;
while (tmp == (tmp / 10) * 10) {
tmp /= 10;
}
}
}
return result;
}
}
[LeetCode]#124 Binary Tree Maximum Path Sum
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
class Result {
public int max; // max path not necessarily from current root to leaf
public int maxPath; // max path from current root to leaf node
public Result(int max, int maxPath) {
this.max = max;
this.maxPath = maxPath;
}
}
public int maxPathSum(TreeNode root) {
if (root == null) {
return 0;
}
Result result = getMaxPathSum(root);
return result.max;
}
public Result getMaxPathSum(TreeNode root) {
if (root == null) {
return new Result(Integer.MIN_VALUE, Integer.MIN_VALUE);
}
Result left = getMaxPathSum(root.left);
Result right = getMaxPathSum(root.right);
int maxPath = Math.max(0, Math.max(left.maxPath, right.maxPath)) + root.val;
int maxChild = Math.max(left.max, right.max);
int maxPassRoot = Math.max(0, left.maxPath) + Math.max(0, right.maxPath) + root.val;
int max = Math.max(maxPath, Math.max(maxChild, maxPassRoot));
return new Result(max, maxPath);
}
}
[笔记整理] 九章算法第五章 Dynamic Programming
1. 如何想到使用DP?
(1) Cannot sort
(2) One of the following three:
a) Find minimum/maximum result
b) Decide whether something is possible or not
c) Count all possible solutions
2. DP题目分类
2.1 Matrix DP
(1) Unique Path
http://codechen.blogspot.com/2016/07/leetcode-114-unique-path.html
(2) Unique Path II
http://codechen.blogspot.com/2016/07/leetcode-63-unique-paths-ii.html
(3) Minimum Path Sum
http://codechen.blogspot.com/2016/07/leetcode-64-minimum-path-sum.html
2.2 Sequence DP
(1) Climbing Stairs
http://codechen.blogspot.com/2016/07/leetcode-70-climbing-stairs.html
(2) Jump Game
http://codechen.blogspot.com/2016/07/leetcode-55-jump-game.html
(3) Jump Game II
(4) Palindrome Partitioning II
http://codechen.blogspot.com/2016/07/lintcode-108-palindrome-partitioning-ii.html
(5) Word Break
http://codechen.blogspot.com/2016/07/leetcode-139-word-break.html
* Word Break II (Not DP problem, use recursion + pruning)
http://codechen.blogspot.com/2016/08/leetcode-140-word-break-ii.html
(6) Longest Increasing Subsequence
http://codechen.blogspot.com/2016/08/leetcode-300-longest-increasing.html
(7) Combination Sum IV
http://codechen.blogspot.com/2016/07/leetcode-377-combination-sum-iv.html
2.3 Two Sequence DP
(1) Longest Common Subsequence
http://codechen.blogspot.com/2016/08/lintcode-77-longest-common-subsequence.html
(2) Longest Common Substring
http://codechen.blogspot.com/2016/08/lintcode-79-longest-common-substring.html
(3) Edit Distance
http://codechen.blogspot.com/2016/08/lintcode-119-edit-distance.html
(4) Distinct Subsequences
http://codechen.blogspot.com/2016/08/leetcode-115-distinct-subsequences.html
(5) Interleaving String
http://codechen.blogspot.com/2016/08/leetcode-29-interleaving-string.html
2.4 Backpack
(1) K Sum
http://codechen.blogspot.com/2016/08/lintcode-89-k-sum.html
(2) 最小调整代价
n 个数,可以对每个数字进行调整,使得相邻2个数的插都<target,调整费用为:
sigma(|A[i] - B[i]|), A为原序列,B为调整后的序列;
求最小调整代价
(1) Cannot sort
(2) One of the following three:
a) Find minimum/maximum result
b) Decide whether something is possible or not
c) Count all possible solutions
2. DP题目分类
2.1 Matrix DP
(1) Unique Path
http://codechen.blogspot.com/2016/07/leetcode-114-unique-path.html
(2) Unique Path II
http://codechen.blogspot.com/2016/07/leetcode-63-unique-paths-ii.html
(3) Minimum Path Sum
http://codechen.blogspot.com/2016/07/leetcode-64-minimum-path-sum.html
2.2 Sequence DP
(1) Climbing Stairs
http://codechen.blogspot.com/2016/07/leetcode-70-climbing-stairs.html
(2) Jump Game
http://codechen.blogspot.com/2016/07/leetcode-55-jump-game.html
(3) Jump Game II
(4) Palindrome Partitioning II
http://codechen.blogspot.com/2016/07/lintcode-108-palindrome-partitioning-ii.html
(5) Word Break
http://codechen.blogspot.com/2016/07/leetcode-139-word-break.html
* Word Break II (Not DP problem, use recursion + pruning)
http://codechen.blogspot.com/2016/08/leetcode-140-word-break-ii.html
(6) Longest Increasing Subsequence
http://codechen.blogspot.com/2016/08/leetcode-300-longest-increasing.html
(7) Combination Sum IV
http://codechen.blogspot.com/2016/07/leetcode-377-combination-sum-iv.html
2.3 Two Sequence DP
(1) Longest Common Subsequence
http://codechen.blogspot.com/2016/08/lintcode-77-longest-common-subsequence.html
(2) Longest Common Substring
http://codechen.blogspot.com/2016/08/lintcode-79-longest-common-substring.html
(3) Edit Distance
http://codechen.blogspot.com/2016/08/lintcode-119-edit-distance.html
(4) Distinct Subsequences
http://codechen.blogspot.com/2016/08/leetcode-115-distinct-subsequences.html
(5) Interleaving String
http://codechen.blogspot.com/2016/08/leetcode-29-interleaving-string.html
2.4 Backpack
(1) K Sum
http://codechen.blogspot.com/2016/08/lintcode-89-k-sum.html
(2) 最小调整代价
n 个数,可以对每个数字进行调整,使得相邻2个数的插都<target,调整费用为:
sigma(|A[i] - B[i]|), A为原序列,B为调整后的序列;
求最小调整代价
2016年8月11日星期四
[LintCode] #89 K Sum
public class Solution {
/**
* @param A: an integer array.
* @param k: a positive integer (k <= length(A))
* @param target: a integer
* @return an integer
*/
// state: f[i][j][t] - for the first i elements in A, pick j elements, how many solutions are there to get sum = t
// function: f[i][j][t] = f[i - 1][j - 1][t - A[i]] + f[i - 1][j][t]
// initialize: f[0][0][0] = 1;
// result: f[A.length][k][target]
public int kSum(int A[], int k, int target) {
// write your code here
if (A == null || A.length == 0 || k == 0) {
return 0;
}
int[][][] f = new int[A.length + 1][k + 1][target + 1];
for (int i = 0; i <= A.length; i++) {
for (int j = 0; j <= k; j++) {
for (int t = 0; t <= target; t++) {
if (j == 0 && t == 0) {
f[i][j][t] = 1;
break;
} else if (i == 0) {
f[i][j][t] = 0;
break;
} else if (j != 0 && t - A[i - 1] >= 0) {
f[i][j][t] = f[i - 1][j - 1][t - A[i - 1]];
}
f[i][j][t] += f[i - 1][j][t];
}
}
}
return f[A.length][k][target];
}
}
[LeetCode] #29 Interleaving String
public class Solution {
/**
* Determine whether s3 is formed by interleaving of s1 and s2.
* @param s1, s2, s3: As description.
* @return: true or false.
*/
// state: dp[i][j] - whether s3.substring(0, i + j) is formed by s1.substring(0, i) and s2.substring(0, j)
// function: dp[i][j] = (s3[i+j] == s1[i] && dp[i - 1][j]) ||
// (s3[i+j] == s2[j] && dp[i][j - 1])
// initialize: dp[0][0] = true
// dp[i][0] = s3[i] == s1[i] && dp[i - 1][0]
// result: dp[s1.length()][s2.length()]
public boolean isInterleave(String s1, String s2, String s3) {
// write your code here
if (s1 == null || s2 == null || s3 == null) {
return false;
}
if (s1.length() + s2.length() < s3.length()) {
return false;
}
boolean[][] dp = new boolean[s1.length() + 1][s2.length() + 1];
dp[0][0] = true;
for (int i = 1; i <= s1.length() && i <= s3.length(); i++) {
dp[i][0] = (s1.charAt(i - 1) == s3.charAt(i - 1) && dp[i - 1][0]);
}
for (int j = 1; j <= s2.length() && j <= s3.length(); j++) {
dp[0][j] = (s2.charAt(j - 1) == s3.charAt(j - 1) && dp[0][j - 1]);
}
for (int i = 1; i <= s1.length(); i++) {
for (int j = 1; j <= s2.length() && i + j <= s3.length(); j++) {
dp[i][j] = (s1.charAt(i - 1) == s3.charAt(i + j - 1) && dp[i - 1][j]) || (s2.charAt(j - 1) == s3.charAt(i + j - 1) && dp[i][j - 1]);
}
}
return dp[s1.length()][s2.length()];
}
}
2016年8月10日星期三
[LeetCode] #115 Distinct Subsequences
public class Solution {
// state: f[i][j] - number of distinct subsequence of T.substring(0, j] in S.substring(0, i]
// function: f[i][j] = f[i - 1][j] + (f[i - 1][j - 1], if T[j] == S[i]) // Attn!
// initialize: f[i][0] = 1
// result f[T.length()][S.length()]
public int numDistinct(String s, String t) {
if (s == null || t == null || s.length() == 0 || t.length() == 0) {
return 0;
}
int[][] f = new int[s.length() + 1][t.length() + 1];
for (int i = 0; i <= s.length(); i++) {
f[i][0] = 1;
}
for (int i = 1; i <= s.length(); i++) {
for (int j = 1; j <= t.length(); j++) {
f[i][j] = f[i - 1][j];
if (t.charAt(j - 1) == s.charAt(i - 1)) {
f[i][j] += f[i - 1][j - 1];
}
}
}
return f[s.length()][t.length()];
}
}
http://www.cs.cmu.edu/~yandongl/distinctseq.html
2016年8月8日星期一
[LintCode] #119 Edit Distance
public class Solution {
/**
* @param word1 & word2: Two string.
* @return: The minimum number of steps.
*/
// state: f[i][j] - min steps to convert word1.substring(0,i) to word2.substring(0,j) , Attn: when i = 0, j = 0
// function: f[i][j] = f[i - 1][j - 1], word1[i] == word2[j]
// = Min(f[i - 1][j - 1], f[i - 1][j], f[i][j - 1]) + 1, word1[i] != word2[j]
// initialze: f[i][0] = i - 1, word1[0] != word2[0]
// f[0][i] = i - 1
// result: f[m][n]
public int minDistance(String word1, String word2) {
// write your code here
if (word1 == null || word2 == null || (word1.length() == 0 && word2.length() == 0)) {
return 0;
}
if (word1.length() == 0 || word2.length() == 0) {
return word1.length() == 0 ? word2.length() : word1.length();
}
int[][] f = new int[word1.length() + 1][word2.length() + 1]; // Attn:Why +1?
for (int i = 0; i <= word1.length(); i++) {
f[i][0] = i;
}
for (int j = 0; j <= word2.length(); j++) {
f[0][j] = j;
}
for (int i = 1; i <= word1.length(); i++) {
for (int j = 1; j <= word2.length(); j++) {
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
f[i][j] = f[i - 1][j - 1];
} else {
f[i][j] = Math.min(f[i - 1][j - 1], Math.min(f[i][j - 1], f[i - 1][j])) + 1;
}
}
}
return f[word1.length()][word2.length()];
}
}
2016年8月7日星期日
[LintCode] #79 Longest Common Substring
public class Solution {
/**
* @param A, B: Two string.
* @return: the length of the longest common substring.
*/
// state: f[i][j] - length of LCS of A.substring(0, i] and B.substring(0, j]
// function: f[i][j] = f[i - 1][j - 1] + 1, if A[i] == B[j]
// = 0, if A[i] != B[j]
// initialize:
// result: f[0...A.length - 1][0...B.length - 1]
public int longestCommonSubstring(String A, String B) {
if (A == null || B == null || A.length() == 0 || B.length() == 0) {
return 0;
}
int max = 0;
int[][] f = new int[A.length()][B.length()];
for (int i = 0; i < A.length(); i++) {
f[i][0] = A.charAt(i) == B.charAt(0) ? 1 : 0;
max = Math.max(max, f[i][0]);
}
for (int j = 0; j < B.length(); j++) {
f[0][j] = A.charAt(0) == B.charAt(j) ? 1 : 0;
max = Math.max(max, f[0][j]);
}
for (int i = 1; i < A.length(); i++) {
for (int j = 1; j < B.length(); j++) {
if (A.charAt(i) == B.charAt(j)) {
f[i][j] = f[i - 1][j - 1] + 1;
} else {
f[i][j] = 0;
}
max = Math.max(max, f[i][j]);
}
}
return max;
}
}
2016年8月4日星期四
[LintCode] #77 Longest Common Subsequence
public class Solution {
/**
* @param A, B: Two strings.
* @return: The length of longest common subsequence of A and B.
*/
// state: f[i][j] - longest LCS of A.substring(0, i] and B.substring(0, j]
// function: f[i][j] = f[i - 1][j - 1] + 1, if A[i] == B[j]
// = Max(f[i - 1][j], f[i][j - 1]), if A[i] != B[j]
// initialize: f[i][0] = A[i] == B[0] ? 1 : 0,f[0][i] = A[0] == B[i] ? 1 : 0
// result: f[A.length - 1][B.length - 1]
public int longestCommonSubsequence(String A, String B) {
// write your code here
if (A == null || B == null || A.length() == 0 || B.length() == 0) {
return 0;
}
int[][] f = new int[A.length()][B.length()];
for (int i = 0; i < A.length(); i++) {
f[i][0] = A.charAt(i) == B.charAt(0) ? 1 : 0;
}
for (int j = 0; j < B.length(); j++) {
f[0][j] = A.charAt(0) == B.charAt(j) ? 1 : 0;
}
for (int i = 1; i < A.length(); i++) {
for (int j = 1; j < B.length(); j++) {
if (A.charAt(i) == B.charAt(j)) {
f[i][j] = f[i - 1][j - 1] + 1;
} else {
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]);
}
}
}
return f[A.length() - 1][B.length() - 1];
}
}
[LeetCode] #300 Longest Increasing Subsequence
public class Solution {
// state: f[i] - length of LIS for nums[0...i]
// function: f[i] = (Max(f[j] + 1), if nums[j] < nums[i]), for all 0 < j < i
// initialze: f[0] = 1
// result: Max(f[0...nums.length-1]) //Attn!
public int lengthOfLIS(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int[] f = new int[nums.length];
int maxLength = 1;
for (int i = 0; i < nums.length; i++) {
f[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
f[i] = Math.max(f[i], f[j] + 1);
maxLength = Math.max(maxLength, f[i]);
}
}
}
return maxLength;
}
}
[LeetCode] #140 Word Break II
Recursion, time complexity: O(2^n), Time Limit Exceeded
public class Solution {
public List<String> wordBreak(String s, Set<String> wordDict) {
List<String> result = new ArrayList<String>();
if (s == null || s.length() == 0) {
return result;
}
helper(s, wordDict, result, new ArrayList<String>(), 0);
return result;
}
private void helper(String s, Set<String> wordList, List<String> result, List<String> path, int start) {
if (start == s.length()) {
result.add(String.join(" ", path));
return;
}
for (int i = start + 1; i <= s.length(); i++) {
if (wordList.contains(s.substring(start, i))) {
path.add(s.substring(start, i));
helper(s, wordList, result, path, i);
path.remove(path.size() - 1);
}
}
}
}
Recursion + pruning(avoid repeated calculation)
public class Solution {
public List<String> wordBreak(String s, Set<String> wordDict) {
List<String> result = new ArrayList<String>();
if (s == null || s.length() == 0) {
return result;
}
boolean[] possible = new boolean[s.length() + 1];
boolean[] initialized = new boolean[s.length() + 1];
Arrays.fill(possible, false);
Arrays.fill(initialized, false);
helper(s, wordDict, result, new ArrayList<String>(), 0, possible, initialized);
return result;
}
private void helper(String s, Set<String> wordList, List<String> result, List<String> path, int start, boolean[] possible, boolean[] initialized) {
if (start == s.length()) {
result.add(String.join(" ", path));
return;
}
for (int i = start + 1; i <= s.length(); i++) {
if (wordList.contains(s.substring(start, i)) && (!initialized[i] || possible[i])) {
int resultN = result.size();
initialized[i] = true;
path.add(s.substring(start, i));
helper(s, wordList, result, path, i, possible, initialized);
path.remove(path.size() - 1);
possible[i] = resultN < result.size();
}
}
}
}
订阅:
博文 (Atom)