Leetcode刷题 2021.01.14

Leetcode1641 统计字典序元音字符串的数目

给你一个整数 n,请返回长度为 n 、仅由元音 (a, e, i, o, u) 组成且按 字典序排列 的字符串数量。

字符串 s 按 字典序排列 需要满足:对于所有有效的 i,s[i] 在字母表中的位置总是与 s[i+1] 相同或在 s[i+1] 之前。

这道题其实完全没想到用dp,就是找找规律然后做出来了,代码其实就是dp的意思(难道已经修炼到独孤九剑的无剑阶段,不知不觉间已经用上dp了,手动狗头)。
其实还是蛮好想的,和元音什么的没关系,一开始1+1+1+1+1,然后 5+4+3+2+1。这样从后往前更新的话,就相当于滚动数组了。
写完一直再想有没有通项公式,推了五分钟推不出来,就算了吧。。

class Solution {
	//初始数组全为1
    int[] arr = new int[]{1, 1, 1, 1, 1};
    public int countVowelStrings(int n) {
    	//更新n - 1次
        for(int i = 1; i < n; i++){
            int sum = 0;
            //从后往前更新
            for(int j = 4; j >= 0; j--){
                sum += arr[j];
                arr[j] = sum;
            }
        }

        int res = 0;
        //最后算下总和
        for(int i = 0; i < arr.length; i++){
            res += arr[i];
        }
        return res;
    }
}

Leetcode1647 字符频次唯一的最小删除次数

如果字符串 s 中 不存在 两个不同字符 频次 相同的情况,就称 s 是 优质字符串 。

给你一个字符串 s,返回使 s 成为 优质字符串 需要删除的 最小 字符数。

字符串中字符的 频次 是该字符在字符串中的出现次数。例如,在字符串 “aab” 中,‘a’ 的频次是 2,而 ‘b’ 的频次是 1 。

这题时间击败了98%,空间只击败20%,不知道哪里出了问题。想法还是比较简单的,先排序,用贪心,每一次保留一个唯一的数字就行。这个数字可能不连续,所以要判断一下。

class Solution {
    public int minDeletions(String s) {
        int[] nums = new int[26];
        char[] arr = s.toCharArray();
		//辅助数组统计字频
        for(int i = 0; i < arr.length; i++){
            nums[arr[i] - 'a']++;
        }
        //排序
        Arrays.sort(nums);
        int index = 25, res = 0, now = nums[25];
        while (index >= 0 && nums[index] != 0){
        	//更新当前唯一的数字,
            now = Math.min(now, nums[index]);
            //如果不是就贪心地加上应该减掉的个数
            if (now != nums[index]){
                res += nums[index] - now;
            }
            //大于0才减一
            if(now > 0) now--;
            index--;
        }

        return res;

    }
}

Leetcode1530 好叶子节点对的数量

给你二叉树的根节点 root 和一个整数 distance 。

如果二叉树中两个 叶 节点之间的 最短路径长度 小于或者等于 distance ,那它们就可以构成一组 好叶子节点对 。

返回树中 好叶子节点对的数量 。

又是二叉树,看评论里说是字节面试题。要是当时给我面这题多好。。二叉树主要还是要考虑应该返回什么,既然要考虑所有叶子节点,就在每一步左右子树返回所有叶子节点到该点的路径长度。然后在根节点上判断是否小于distance,也是自底向上的递归。想好了之后在处理根节点为null,和叶子节点返回什么就可以了。
一开始想找O(n)的,后来看题解也是O(n^2)。要是面试的时候可以和面试官交流能优化到什么时间复杂度吧。

class Solution {
	//结果
    int res = 0;
    public int countPairs(TreeNode root, int distance) {
        helper(root, distance);
        return res;
    }

    private int[] helper(TreeNode root, int distance){		
    	//空结点,返回一个空数组
        if (root == null) return new int[]{};
        //叶子节点返回1
        if (root.left == null && root.right == null) return new int[]{1};
        //自底向下,返回左右子树的叶子节点到root节点的距离
        int[] l = helper(root.left, distance);
        int[] r = helper(root.right, distance);
		
		//O(n^2)找符合条件的叶子节点
        for(int i = 0; i < l.length; i++){
            for(int j = 0; j < r.length; j++){
                if (l[i] + r[j] <= distance) {
                    res++;
                }
            }
        }
        //新建一个数组,把两个合并一起返回给再上一个节点
        int[] arr = new int[l.length + r.length];
        int index = 0;
        for(int i = 0; i < l.length; i++){
            arr[index++] = l[i] + 1;
        }
        for(int i = 0; i < r.length; i++){
             arr[index++] = r[i] + 1;
        }

        return arr;

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值