lintcode做题总结, Oct 07

来源:互联网 发布:双色球黄金分割算法 编辑:程序博客网 时间:2024/05/16 04:36

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];    }}


0 0
原创粉丝点击