以赛促练-力扣第308场周赛反思

文章目录

        • T1.和有限的最长子序列
        • T3.收集垃圾的最少总时间
        • T4.给定条件下构造矩阵

这次周赛是拉着小伙伴们一起打的,希望可以调动大家的刷题氛围,跳出舒适区。

这次周赛整体感觉下来难度是不高的,前三题我都用模拟解决了,但是在解决问题的过程中,碰到一些细节方面总是卡壳,比如第一题就卡了二十几分钟,这是不达标的,整个算法题感还没有完全培养上来,还需要在之后的刷题过程中,理清思路,顺流而下。

T1.和有限的最长子序列

直接模拟就好,我的ac垃圾题解如下,在while里面还加了这么多判断,突出一个乱写。

class Solution {
    public int[] answerQueries(int[] nums, int[] queries) {
        int qlen=queries.length;
        int[]ans=new int[qlen];
        Arrays.sort(nums);
        for(int i=0;i<qlen;i++){
            long target=queries[i];
            long res=0;
            int reslen=0;
            int j=0;
            while(reslen<nums.length&&res<=target){
                res+=nums[reslen++]; 
                if(res>target){
                    reslen--;
                    break;
                }
                if(res==target) break;
            }
            ans[i]=reslen;
            
        }
        return ans;
    }
}

参考TsReaper的题解模拟,先排序,然后就是两层循环,外层循环queries,内层循环nums,内层循环一直加到最后一个数字,提前退出条件就是当前和res已经大于target了,如果一直没有退出,则说明整个数组都可以。

class Solution {
    public int[] answerQueries(int[] nums, int[] queries) {
        Arrays.sort(nums);
        int qLen=queries.length;
        int numLen=nums.length;
        int[]ans=new int[qLen];
        for(int q=0;q<qLen;q++){
            long res=0;
            for(int i=0;i<numLen;i++){
                res+=nums[i];
                if(res>queries[q]){
                    ans[q]=i;
                    break;
                }
            }
            if(res<=queries[q])ans[q]=numLen;
        }
        return ans;
    }
}

T2没什么好说的,直接栈模拟就好了,可以直接用StringBuilder容器模拟,其中删除的api为sb.deleteCharAt(int index)、获取长度为sb.length();

T3.收集垃圾的最少总时间

先贴上我的垃圾ac题解,又臭又长,先是一层循环,把每个种类出现垃圾的地方标出来了,并且把每种垃圾的总和分别计算出来,然后第二次遍历计算前缀和方便自己计算路程,第三次遍历把end求出来,方便利用前缀和求路程。

class Solution {
    public int garbageCollection(String[] garbage, int[] travel) {
        int res=0;
        int garlen=garbage.length;
        int tralen=travel.length;
        boolean[][]exit=new boolean[garlen][3];
        int[]trash=new int[3];
        int[]road=new int[3];
        for(int i=0;i<garlen;i++){
            String g=garbage[i];
            for(int j=0;j<g.length();j++){
                if(g.charAt(j)=='M'){
                    exit[i][0]=true;
                    trash[0]++;
                }
                if(g.charAt(j)=='P'){
                    exit[i][1]=true;
                    trash[1]++;
                }
                if(g.charAt(j)=='G'){
                    exit[i][2]=true;
                    trash[2]++;
                }
            }
        }
        int[]preSum=new int[garlen];
        for(int i=0;i<tralen;i++){
            preSum[i+1]=preSum[i]+travel[i];
        }
        for(int i=0;i<3;i++){
           int end=-1; 
           for(int j=0;j<garlen;j++){
              if(exit[j][i]==true){
                  end=j;
              }
           } 
           if(end!=-1)res+=preSum[end];
        }
        res+=trash[0]+trash[1]+trash[2];
        return res;
    }
}

参考灵神的题解才是简约,只用两次遍历,第一次遍历中,不管什么垃圾,全部加起来就是总垃圾处理时间,并且从上面可以看出,路程我们只需要知道每种类别出现垃圾的最后位置就可以了,因此只需要不断记录一下终点位置。
超简约python题解如下:

class Solution:
    def garbageCollection(self, garbage: List[str], travel: List[int]) -> int:
        ans=0
        # 记录最后一次出现位置
        end=[0]*3
        for index, g in enumerate(garbage):
            ans += len(g)
            for j, c in enumerate("MPG"):
                # 记录最后一次位置
                if c in g:
                    end[j]=index
        # 将三种垃圾的所有路程加起来
        return  ans+sum(sum(travel[:e])for e in end)

T4.给定条件下构造矩阵

知道需要排出一个先后顺序,但不知道采用什么算法,后来参考灵神的题解,知道拓扑排序能够排出元素的相对顺序,而自己之前恰好做过这方面的内容,引路算法学习-拓扑排序。由于行和列是互不影响的,因此可以分别对他们进行拓扑排序。在已经排序的情况下,通过字典标号,在结果矩阵中进行填充。

class Solution {
    public int[][] buildMatrix(int k, int[][] rowConditions, int[][] colConditions) {
        int[]rowTopo=topoSort(k,rowConditions);
        int[]colTopo=topoSort(k,colConditions);
        //没有同时满足限制的
        if(rowTopo.length!=k||colTopo.length!=k) return new int[][]{};
        //先指定数字的col位置,前面的数字应该列号小,以数组进行字典映射,key数字-value列号
        int[]pos=new int[k];
        for(int i=0;i<k;i++){
            pos[colTopo[i]]=i;
        }
        int[][]ans=new int[k][k];
        //从row=0开始一行一行排列,前面的数字row[i]应该行号小
        for(int i=0;i<k;i++){
            ans[i][pos[rowTopo[i]]]=rowTopo[i]+1;
        }
        return ans;
    }
    public int[] topoSort(int k,int[][]map){
        ArrayList<Integer>[] g=new ArrayList[k];
        //初始化g中所有的HashSet<>();
        Arrays.setAll(g,e->new ArrayList<Integer>());
        int[]inD=new int[k];
        for(int[]m:map){
            //顶点编号从0开始
            g[m[0]-1].add(m[1]-1);
            inD[m[1]-1]++;
        }
        ArrayDeque<Integer> que=new ArrayDeque<>();
        for(int i=0;i<k;i++){
            if(inD[i]==0) que.add(i);
        }
        ArrayList<Integer> res=new ArrayList<>();
        while(!que.isEmpty()){
            int top=que.poll();
            res.add(top);
            for(int i:g[top]){
                if(--inD[i]==0) que.offer(i);
            }
        }
        //ArrayList转int[]
        return res.stream().mapToInt(x->x).toArray();
    }
}

你可能感兴趣的:(算法人生,leetcode,算法,职场和发展)