Leetcode Weekly Contest 226(详细解析)

题目链接: Leetcode Weekly Contest 226

写在前面:

本次周赛又是尴尬只做了第一题,寒假得多刷题了。

1、1742. Maximum Number of Balls in a Box

难度:Easy

题目大意:

将小球按照一定规则放入特定的盒子里,求单个盒子中小球数量的最大值。

思路:

按题目要求进行模拟即可。

代码

class Solution {
    public int countBalls(int lowLimit, int highLimit) {
        //箱子编号最大值为9+9+9+9+9=45(球的编号为99999)
        int[] box=new int[46];//下标从0~45
        for(int i=lowLimit;i<=highLimit;i++){
            int sum=0;//各个位上的数字之和
            int a=i;//把i的值赋给a,对i直接运算会导致i的值发生变化,影响for循环
            while(a>0){
                sum+=(a%10);
                a/=10;
            }
            box[sum]++;
        }
        int res=0;
        for(int i=1;i<46;i++){
            if(box[i]>res){
                res=box[i];
            }
        }
        return res;
    }
}

2、1743. Restore the Array From Adjacent Pairs

难度:Medium

题目大意:

给出若干个长度为2的子数组,子数组内两个数在原数组中是相邻的,要求根据这些子数组恢复出原数组。

思路:

参考高赞回答,用map存储各个元素的相邻元素,如何遍历,只有一个邻居的元素为原数组的第一个元素,然后根据相邻元素的信息依次递推出后面的元素。

代码

class Solution {
    public int[] restoreArray(int[][] pairs) {
        Map<Integer,List<Integer>> map=new HashMap<Integer,List<Integer>>();
        for(int[] arr:pairs){//用map存储各个元素的相邻元素
            if(!map.containsKey(arr[0])){//arr[1]是arr[0]的相邻元素
                List<Integer> temp=new ArrayList<Integer>();
                temp.add(arr[1]);
                map.put(arr[0],temp);
            }
            else{
                map.get(arr[0]).add(arr[1]);
            }
            if(!map.containsKey(arr[1])){//arr[0]是arr[1]的相邻元素
                List<Integer> temp=new ArrayList<Integer>();
                temp.add(arr[0]);
                map.put(arr[1],temp);
            }
            else{
                map.get(arr[1]).add(arr[0]);
            }
        }
        int start=0;//表示第一个元素
        for(int key:map.keySet()){//寻找第一个元素
            if(map.get(key).size()==1){//只有一个相邻元素
                start=key;
                break;
            }
        }
        int len=pairs.length;
        int[] res=new int[len+1];
        Set<Integer> set=new HashSet<Integer>();//用来存储遍历过的元素
        int count=0;
        res[count++]=start;
        set.add(start);
        for(int i=1;i<=len;i++){
            List<Integer> list=map.get(res[i-1]); 
            int value=0;//下一个元素
            if(list.size()==1){
                value=list.get(0);
            }
            else{
                if(set.contains(list.get(0))){
                    value=list.get(1);
                }
                else{
                    value=list.get(0);
                }
            }
            res[count++]=value;
            set.add(value);
        }
        return res;
    }
}

 

3、1744. Can You Eat Your Favorite Candy on Your Favorite Day?

难度:Medium

题目大意:

判断能否在特定的某一天吃到最喜欢的某种糖果。

思路:

题目比较长,需要花一定时间理解,理解之后难度不大。关键在于两个临界条件的判断,本题还需要主要天数是从第0天开始算的,同时要注意数据类型和范围的问题,用int会溢出。

代码

class Solution {
    public boolean[] canEat(int[] candiesCount, int[][] queries) {
        int n=queries.length;
        int len=candiesCount.length;
        long[] prefixSum=new long[len+1];//前缀和
        prefixSum[0]=0;
        for(int i=1;i<len+1;i++){
            prefixSum[i]=prefixSum[i-1]+candiesCount[i-1];//prefixSum[i]表示candiesCount[i]前面所有元素之和
        }
        boolean[] ans=new boolean[n];
        for(int i=0;i<n;i++){
            int type=queries[i][0];
            long day=queries[i][1];
            int cap=queries[i][2];
            if(prefixSum[type]-day*cap>=cap){//吃不完前面的糖果,注意有一种情况是一天之内可能吃多种糖果,所以是>=cap而不是>=0
                ans[i]=false;
            }
            else if(prefixSum[type+1]-1<day){//每天吃一个都撑不到第day天(注意有第0天)
                ans[i]=false;
            }
            else{
                ans[i]=true;
            }
            
        }
        return ans;
    }
}

4、1745. Palindrome Partitioning IV

难度:Hard

题目大意:

很经典的一道题。判断能否将字符串分割成3个子字符串,使得这三个子字符串都是回文串。

思路

因为字符串长度在2000以内,暴力求解就能过。判断字符串是否为回文串如果一个字符一个字符地进行比较会超时,用DP打表来进行判断。

代码

class Solution {
    public boolean checkPartitioning(String s) {
        int n=s.length();
        char[] arr=s.toCharArray();
        boolean[][] dp=new boolean[n][n];//dp[i][j]表示s[i,j]为回文字符串
        for(int i=n-1;i>=0;i--){
            for(int j=i;j<n;j++){
                if(j==i){
                    dp[i][j]=true;
                }
                else if(j-i==1){
                    dp[i][j]=(arr[i]==arr[j]);
                }
                else{//字符串长度大于2
                    dp[i][j]=(arr[i]==arr[j])&&dp[i+1][j-1];
                    //因为dp[i][j]与dp[i+1][j-1]有关,所有i要从大到小遍历,j要从小到大遍历
                }
            }
        }
        
        for(int l=1;l<=n-2;l++){
            for(int r=l;r<n-1;r++){
                if(dp[0][l-1]&&dp[l][r]&&dp[r+1][n-1]){
                    return true;
                }
            }
        }
        return false;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值