Leetcode--2021.7.18周赛

emmm这次的周赛好难呀,能ac前两题就能进行前500,我耗时有点久,排700+。。。看到矩阵和树的题我就很懵逼,下一阶段要加强这方面的学习了。前两题都是直接ac,第三题想了一会dp,结果没啥思路,第四题可以实现,但是超时了,最后也没优化出来。。下面是解题思路和代码

第一题—5161. 可以输入的最大单词数

在这里插入图片描述

思路

因为是比赛,所以要尽可能的在最短的时间做出来,所以直接使用的暴力方法:

  1. 把不能输入的单词存入set集合;
  2. 每个输入的单词进行遍历(使用string.split(“ ”)分割每一个单词),如果set中的某一个字符在其中的话,则不能输入;
  3. 如果其中不包含set中的元素,则ans++;
  4. 最后返回ans

时间复杂度为 O ( n ) O(n) O(n)ntext中除空格之外的字母的数量

代码

class Solution {
    public int canBeTypedWords(String text, String brokenLetters) {
        Set<Character> bad = new HashSet<>();
        for (char ch : brokenLetters.toCharArray())
            bad.add(ch);
        int ans = 0;
        for (String s : text.split(" "))
        {
//            System.out.println(s);
            int sign = 0;
            for (char ch : s.toCharArray())
                if (bad.contains(ch)){
                    sign = 1;
                    break;
                }
            if (sign==0)
                ans++;
        }

        return ans;
    }
}

第二题—5814. 新增的最少台阶数

在这里插入图片描述
在这里插入图片描述

思路

看到这个题第一反应是动态规划,后来发现根本不需要。
题目要求是需要添加的最少台阶数,每次从0开始(这点很重要),所以

  1. 如果两个ij之间的距离大于dist,则其中必定需要添加台阶,添加台阶的数量由下式决定 n = c e i l ( 1.0 ∗ ( j − i ) / d i s t ) − 1 n = ceil(1.0*(j-i)/dist) - 1 n=ceil(1.0(ji)/dist)1

所以算法步骤为:

  1. 因为第一阶台阶一定是0,所以对第一步进行特殊处理;
  2. 依次遍历rungs中的每一个元素,计算其是否需要添加台阶;
  3. 返回添加台阶的数量;

时间复杂度为 O ( n ) O(n) O(n)n数组rungs的长度

代码

class Solution {
    public int addRungs(int[] rungs, int dist) {
        int ans = 0;

        int cur = (int) (Math.ceil(1.0 * rungs[0]/dist)) - 1;
        ans = cur;
//        System.out.println(ans);
        for (int i=1;i<rungs.length;i++)
        {
            cur = (int) (Math.ceil(1.0*(rungs[i]-rungs[i-1])/dist)) - 1;
//            System.out.println(cur);
            ans += cur;
        }

        return ans;
    }
}

第三题—5815. 扣分后的最大得分

在这里插入图片描述
在这里插入图片描述

思路

没啥思路,后续学习后再更新。

代码

第四题—5816. 查询最大基因差

在这里插入图片描述
在这里插入图片描述

思路

emm,超时了,先放上超时的代码,学习其他的方法后再来更新。

超时思路:

  1. 因为给定的树的结构不是层层递进的,不太会直接这样构造树,所以使用HashMap辅助存储,(key,value)对应(当前节点,当前节点的父节点),并记录根节点的值;
  2. 遍历查询数组queries中的每一对数组,获取val与该节点到根节点路径上所有结点的异或结果,将最大的异或结果存储到结果数组ans中;

超时了,因为时间复杂度最大为 3 ∗ 1 0 4 ∗ 1 0 5 3*10^4*10^5 3104105(因为如果在每一个结点都只有一个子节点的情况下,树的层数为1e5,如果queries数组中全部都是对最后一个叶节点进行查询的话,就是这个复杂度),远远大于1e7

所以优化的关键是优化获取queries中的每一对元素查询最大异或结果的时间复杂度为O(1),这样的话整个程序的时间复杂度降为 3 ∗ 1 0 4 3*10^4 3104,不再超时。

目前还没想到合适的方法,有时间去学习一下大佬们的解法。

代码–超时代码


class Solution {
    public int[] maxGeneticDifference(int[] parents, int[][] queries) {
        Map<Integer,Integer> map = new HashMap<>();
        int root = -1;
        for (int i = 0;i< parents.length;i++)
        {
            map.put(i,parents[i]);//当前点的值及其父节点的值
            if (parents[i]==-1)
                root = i;
        }
        int len = queries.length;
        int[] ans = new int[len];

        for (int i=0;i<len;i++)
        {
            int node = queries[i][0];
            int val = queries[i][1];
            int max = node ^ val;
//            System.out.println(" node "+node+" val "+val+" max "+max);



            while(map.get(node)!=-1)
            {
                node = map.get(node);
                max = Math.max(max,val^node);
//                System.out.println(" node "+node+" max "+max);
            }

            max = Math.max(max,val^root);

            ans[i] = max;
        }


        return ans;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值