lintcode做题总结, Oct 07

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值