LeetCode 基础题目2

LeetCode 基础题目2

205. 同构字符串

class Solution {
    public boolean isIsomorphic(String s, String t) {
        HashMap<Character,Character> s2t = new HashMap();
        HashMap<Character,Character> t2s = new HashMap();
        int l=s.length();
        for(int i=0;i<l;i++){
            char si=s.charAt(i),ti=t.charAt(i);
            if(s2t.containsKey(si)&&ti!=s2t.get(si))
                return false;
            if(t2s.containsKey(ti)&&si!=t2s.get(ti))
                return false;
            s2t.put(si,ti);
            t2s.put(ti,si);
        }
        return true;
    }
}

语法知识点主要是在String类的使用上,注意不支持下标访问,使用charAt得到对应位置字符,详细函数见Java String类。其次,注意HashMap需要传包装类而不是基本类型见Java HashMap类。

解法比较容易,但是注意如何简化条件。该题的主要思路是建立字符串对应位置字母的映射,使用哈希表可以完成这一点,并且根据条件理解可得两串中的字符是一一对应的,所以两个映射集合的键值对刚好相反。且根据位置关系不能乱序可得只需同时处理相同位置的字母即可。于是,只要处理位置的字符都不存在其对应,则建立两字符的双射,否则检查存在映射的字符是否正确映射了对应字符即可。

392. 判断子序列

针对本题来说使用O(n)的双指针肯定更好一点

class Solution {
    public boolean isSubsequence(String s, String t) {
        int sp=0,tp=0;
        while(sp<s.length()&&tp<t.length()){
            if(s.charAt(sp)==t.charAt(tp))
                sp++;
            tp++;
        }
        if(sp==s.length()) return true;
        return false;
    }
}

没有什么好记录的,依次比较对应位置的字符即可。

官方的动态规划解法如下,主要是针对大量的输入字符串通过动态规划可以优化

class Solution {
    public boolean isSubsequence(String s, String t) {
        int n = s.length(), m = t.length();

        int[][] f = new int[m + 1][26];
        for (int i = 0; i < 26; i++) {
            f[m][i] = m;
        }

        for (int i = m - 1; i >= 0; i--) {
            for (int j = 0; j < 26; j++) {
                if (t.charAt(i) == j + 'a')
                    f[i][j] = i;
                else
                    f[i][j] = f[i + 1][j];
            }
        }
        int add = 0;
        for (int i = 0; i < n; i++) {
            if (f[add][s.charAt(i) - 'a'] == m) {
                return false;
            }
            add = f[add][s.charAt(i) - 'a'] + 1;
        }
        return true;
    }
}

思路是从下往上,二维数组的每行表示的是从该位置起,之后的字母在串中可以被最早找到的位置,得到这样的数组需要从下往上(从后往前)更新,每次更新本字母所在的行的该字母位置为串中的位置,其余为上一层数组的值。更新完毕后,从头至尾扫描子串是否存在的方法是,如果寻找一个字符时发现其位于字符串尾部(end处,非最后一个元素),则表明未找到完整的子串。如果找到了一个字符的位置不为字符串末尾,则到达该字符的下一行开始寻找这个字符之后是否能找到其他字符。

剑指 Offer II 049. 从根节点到叶节点的路径数字之和

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int sumNumbers(TreeNode root) {
        return dfsCount(root,0);
    }
    public int dfsCount(TreeNode node,int preSum){
        if(node==null) return 0;
        if(node.left==null&&node.right==null) 
            return preSum*10+node.val;
        return dfsCount(node.left,preSum*10+node.val)+dfsCount(node.right,preSum*10+node.val);
    }
}

这也是白给的题目,1分钟秒了,通过前序遍历可以访问从根到叶子节点的路径,也可以说是分治,到达叶子节点后将值计入答案即可,每到达一个节点都需要将之前节点的值乘10再加上节点的值得到当前路径的和,并传入子节点。而左子树和右子树的和即为节点的和。

你可能感兴趣的:(leetcode,算法)