LeetCode 第二十九天

1. 完全二叉树插入器

完全二叉树 是每一层(除最后一层外)都是完全填充(即,节点数达到最大)的,并且所有的节点都尽可能地集中在左侧。

设计一种算法,将一个新节点插入到一个完整的二叉树中,并在插入后保持其完整。

实现 CBTInserter 类:

  • CBTInserter(TreeNode root) 使用头节点为 root 的给定树初始化该数据结构;
  • CBTInserter.insert(int v) 向树中插入一个值为 Node.val == val的新节点TreeNode。使树保持完全二叉树的状态,并返回插入节点 TreeNode 的父节点的值;
  • CBTInserter.get_root() 将返回树的头节点。

分析:

使用一个List才存储树的节点。当调用CBTInserter(TreeNode root)时,按照层序遍历的顺序把各个节点add到List中;调用CBTInserter.insert(int v) 时遍历List,找到插入节点的位置:如果当前节点root的左子树为空则root.left = node,如果右子树为空则root.right = node;调用CBTInserter.get_root()直接返回List(0)。

class CBTInserter {
    List<TreeNode> list = new ArrayList<>();
    int idx = 0;

    public CBTInserter(TreeNode root) {
        list.add(root);
        int cur = 0;
        while (cur < list.size()){
            TreeNode node = list.get(cur);
            if (node.left != null) list.add(node.left);
            if (node.right != null) list.add(node.right);
            cur++;
        }
    }

    public int insert(int val) {
        TreeNode node = new TreeNode(val);
        while (list.get(idx).left != null && list.get(idx).right != null) idx++;
        TreeNode n = list.get(idx);
        if (n.left == null) n.left = node;
        else if (n.right == null) n.right = node;
        list.add(node);
        return n.val;

    }

    public TreeNode get_root() {
        return list.get(0);

    }
}

2. 分数加减运算

给定一个表示分数加减运算的字符串 expression ,你需要返回一个字符串形式的计算结果。

这个结果应该是不可约分的分数,即最简分数。 如果最终结果是一个整数,例如 2,你需要将它转换成分数形式,其分母为 1。所以在上述例子中, 2 应该被转换为 2/1。

分析:

模拟整个的计算过程。记录分子和分母并不断地更新他们直到最后。初始化分子fz=0, 分母fm=1; 定义一个sign来记录正负号,遍历得到fz1和fm1,更新fz,fm:signfz=fzfm1+fmfz1 fm=fmfm1,得到新的fz和fm之后计算它们的最大公约数g对分数进行约分:fz=fz/g,fm=fm/g。

class Solution {
    public String fractionAddition(String expression) {
        long fz = 0, fm = 1;
        int i = 0;
        while (i < expression.length()) {
            int sign = 1;
            long fz1 = 0;
            if (expression.charAt(i) == '-' || expression.charAt(i) == '+'){
                sign = expression.charAt(i) == '-' ? -1 : 1;
                i++;
            }
            while (i < expression.length() && Character.isDigit(expression.charAt(i))) {
                fz1 = fz1 * 10 + expression.charAt(i) - '0';
                i++;
            }
            fz1 = sign * fz1;
            i++;
            long fm1 = 0;
            while (i < expression.length() && Character.isDigit(expression.charAt(i))) {
                fm1 = fm1 * 10 + expression.charAt(i) - '0';
                i++;
            }
            fz = fz * fm1 + fm * fz1;
            fm *= fm1;
        }
        if (fz == 0){
            return "0/1";
        }
        long g = gcd(Math.abs(fz), fm);
        return Long.toString(fz/g) + "/" + Long.toString(fm/g);


        }


    public long gcd(long a, long b) {
        long remainder = a % b;
        while (remainder != 0) {
            a = b;
            b = remainder;
            remainder = a % b;
        }
        return b;
    }

}

3. 字符串中的变位词

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的某个变位词。换句话说,第一个字符串的排列之一是第二个字符串的子串 。

分析:

使用滑动窗口。设s1的长度为n,s2的长度为m,只有m>=n,题目才有意义。因为是要判断s2中是否有s1的排列之一,那么长度一定是n,故滑动窗口的大小设置为n。定义两个数组count1,count2来记录s1中字母出现的次数和s2中当前滑动窗口内字母出现的次数,当count1与count2相等时返回true。

class Solution {
    public boolean checkInclusion(String s1, String s2) {
        int n = s1.length(), m = s2.length();
        if (n > m) return false;
        int[] count1 = new int[26];
        int[] count2 = new int[26];
        for (int i = 0; i < n; i++) {
            count1[s1.charAt(i) - 'a']++;
            count2[s2.charAt(i) - 'a']++;
        }
        if (Arrays.equals(count1, count2)) return true;
        for (int i = n; i < m; i++) {
            count2[s2.charAt(i) - 'a']++;
            count2[s2.charAt(i-n) - 'a']--;
            if (Arrays.equals(count1, count2)){
                return true;
            }
        }
        return false;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值