1. Scramble String 这道题代码没几行但是用了三维DP还是很复杂的,用[i][j][k]代表从s1.charAt(i)和s2.charAt(j)开始的k的字符的字符串是不是scramble,由于字符变换是基于交换的,所以只要找到那个分界线然后交换判断既可以。
public class Solution {
public boolean isScramble(String s1, String s2) {
if(s1==null || s2==null || s1.length()!=s2.length())
return false;
if(s1.length()==0)
return true;
boolean[][][] res = new boolean[s1.length()][s2.length()][s1.length()+1];
for(int i=0;i<s1.length();i++) {
for(int j=0;j<s2.length();j++) {
res[i][j][1] = s1.charAt(i)==s2.charAt(j);
}
}
for(int len=2;len<=s1.length();len++) {
for(int i=0;i<s1.length()-len+1;i++) {
for(int j=0;j<s2.length()-len+1;j++) {
for(int k=1;k<len;k++) {
res[i][j][len] |= (
// for abc, abc
res[i][j][k]&&res[i+k][j+k][len-k]
// for a|bc, cb|a
|| res[i][j+len-k][k]&&res[i+k][j][len-k]);
}
}
}
}
return res[0][0][s1.length()];
}
}
2. Text Justification 这道题思路并不复杂但是写起来很繁琐,用每行的总空格数除以word间的间隔数就可以找到平均值,然后把余数一次放入各个间隔即可。
public class Solution {
public List<String> fullJustify(String[] words, int L) {
List<String> ans = new ArrayList<String>();
int n = words.length;
int i = 0;
while (i < n) {
int len = words[i].length();
int j = i + 1;
while (j < n && len + 1 + words[j].length() <= L) {
len += 1 + words[j].length();
j++;
}
String line = words[i];
if (j == n) { // if this is the last line
for (int k = i + 1; k < n; k++) {
line += " " + words[k];
}
while (line.length() < L) {
line += " ";
}
} else {
int extraWhite = L - len;
int whiteNum = j - i - 1;
if (whiteNum == 0) { // if this line has only one word
while (line.length() < L) {
line += " ";
}
} else {
for (int k = i + 1; k < j; k++) {
line += " ";
for (int p = 0; p < extraWhite/whiteNum; p++) {
line += " ";
}
if (k - i <= extraWhite%whiteNum) {
line += " ";
}
line += words[k];
}
}
}
ans.add(line);
i = j;
}
return ans;
}
}
3. Trapping Rain Water这道题思路非常巧妙,只需要从左向右保存当时的最大值再从右向左扫一遍,然后去min就是装满水后的总体积,这是在减去原来的就是水的体积。
public class Solution {
public int trap(int[] height) {
if (height == null || height.length <= 2){
return 0;
}
int[] left = new int[height.length];
int[] right = new int[height.length];
int max = height[0];
for (int i = 0; i < height.length; i++){
if (height[i] < max){
left[i] = max;
} else {
left[i] = height[i];
max = height[i];
}
}
max = height[height.length - 1];
for (int i = height.length - 1; i >= 0; i--){
if (height[i] < max){
right[i] = max;
} else {
right[i] = height[i];
max = height[i];
}
}
int res = 0;
for (int i = 0; i < height.length; i++){
res += Math.min(left[i], right[i]) - height[i];
}
return res;
}
}
4.Recover Binary Search Tree 这道题的主要考察点是BST的中序历遍输出是有序的。但是交换可能有两种情况,一种是不在同一位置,这样找到两个逆序即可,还有一种是交换在同一位置,这样就只有一次逆序
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public void recoverTree(TreeNode root) {
if (root == null)
return;
// BST inorder. ele in order list is from large to small 5->4->3->2
LinkedList<TreeNode> order = new LinkedList<TreeNode>();
ArrayList<TreeNode> swap = new ArrayList<TreeNode>();
helper(root, order, swap);
if (swap.size() == 2){
int tmp = swap.get(0).val;
swap.get(0).val = swap.get(1).val;
swap.get(1).val = tmp;
} else if (swap.size() == 3){
int tmp = swap.get(0).val;
swap.get(0).val = swap.get(2).val;
swap.get(2).val = tmp;
}
}
public void helper(TreeNode root, LinkedList<TreeNode> order, ArrayList<TreeNode> swap){
//if having already found the 2 elements with wrong order.
if (root == null || swap.size() == 3)
return;
helper(root.left, order, swap);
if (order.size() != 0 && order.get(0).val > root.val){
//cases like 1,2,3,5,4,6,7
if (swap.size() == 0){
swap.add(order.get(0));
swap.add(root);
//cases like 1,2,6,4,5,3,7
} else {
swap.add(root);
return;
}
}
order.addFirst(root);
helper(root.right, order, swap);
}
}
5. Binary Tree Maximum Path Sum 这道题思路也不复杂,只要使用递归,然后针对每一个节点,更新max
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public int maxPathSum(TreeNode root) {
if (root == null)
return 0;
int max[] = new int[1];
max[0] = root.val;
visit(root, max);
return max[0];
}
public int visit(TreeNode root, int[] max) {
if (root == null)
return 0;
int left = visit(root.left, max);
int right = visit(root.right, max);
int curr = Math.max(root.val, Math.max(root.val + left, root.val + right));
max[0] = Math.max(max[0], Math.max(curr, left + root.val + right));
return curr;
}
}
6. Distinct Subsequences 这道题有点类似于找最长子序列,只是换成了所有子序列的数量,用的是DP(二维优化成一维)
public class Solution {
public int numDistinct(String s, String t) {
int[] res = new int[t.length()];
for (int i = 0; i < s.length(); i++){
for (int j = t.length() - 1; j >= 0; j--){
if (s.charAt(i) == t.charAt(j)) {
res[j] += j==0?1:res[j-1];
}
}
}
return res[t.length()-1];
}
}