[5.23]力扣周赛

[5.23]力扣周赛

一、5763. 哪种连续子字符串更长

给你一个二进制字符串 s 。如果字符串中由 1 组成的 最长 连续子字符串 严格长于0 组成的 最长 连续子字符串,返回 true ;否则,返回 false

在这里插入图片描述

题解:

这题比较简单,直接采用双指针的方法过一遍就可以了,时间复杂度O(n)

  public static boolean checkZeroOnes(String s) {
        int one=0;
        int zero=0;
        int i=0;
        int j=0;
        while(i<s.length()){
            int sum_one=0;
            int sum_zero=0;
            while (j<s.length()&&s.charAt(j)=='0') {
                sum_zero++;
                j++;
            }
            while (j<s.length()&&s.charAt(j)=='1') {
                sum_one++;
                j++;
            }
            one=Math.max(one,sum_one);
            zero=Math.max(zero,sum_zero);
            i=j;
        }
        System.out.println(one+" "+zero);
        return one>zero;
    }

二、5764. 准时到达的列车最小时速

给你一个浮点数 hour ,表示你到达办公室可用的总通勤时间。要到达办公室,你必须按给定次序乘坐 n 趟列车。另给你一个长度为 n 的整数数组 dist ,其中 dist[i] 表示第 i 趟列车的行驶距离(单位是千米)。

每趟列车均只能在整点发车,所以你可能需要在两趟列车之间等待一段时间。

  • 例如,第 1 趟列车需要 1.5 小时,那你必须再等待 0.5 小时,搭乘在第 2 小时发车的第 2 趟列车。

返回能满足你准时到达办公室所要求全部列车的 最小正整数 时速(单位:千米每小时),如果无法准时到达,则返回 -1

在这里插入图片描述

题解一(超时):

采用暴力的方法,首先进行一个分类:

  • 由于最短时间的话也算是一个小时,所以如果时间比数组的长度减一还要短的话,直接输出-1即可
  • 如果时间比数组短但是又比n-1长的话,则只需要考虑数组中最大的数和最后的到达的时间的最大值即可
  • 如果比数组长的话,则进行一个遍历来进行计算
 public int minSpeedOnTime(int[] dist, double hour) {
        int n=dist.length;
        if(hour<=n-1) return -1;
        int res=1;
        int max=0;
        for(int i:dist){
            max=Math.max(i,max);
        }
        if(hour<=n){
            //System.out.println((float)(Math.round((hour-n+1)*100))/100);
            int temp= (int) Math.ceil(dist[n-1]/((float)(Math.round((hour-n+1)*100))/100));
            //System.out.println(temp);
            res=Math.max(max,temp);
            return res;
        }
         else if(hour>n){
            while(res<hour){
                double temp=0;
                for(int i=0;i<n-1;i++){  
                    temp=temp+Math.ceil(dist[i]/(1.0*res));
                    if (temp>hour) break;
                }
                temp+=dist[n-1]/(1.0*res);
                if(temp<=hour) break;
                res++;
            }
        }
        return res;
题解二:(遍历那里使用二分)

!!!过啦

class Solution {
    public int minSpeedOnTime(int[] dist, double hour) {
        int n=dist.length;
        if(hour<=n-1) return -1;
        int res=1;
        int max=0;
        for(int i:dist){
            max=Math.max(i,max);
        }
        if(hour<=n){
            int temp= (int) Math.ceil(dist[n-1]/((float)(Math.round((hour-n+1)*100))/100));
            res=Math.max(max,temp);
            return res;
        }
        else if(hour>n){
            int mid=0;
            int end=10000000;
            while(res<=end){
                mid = res+(end-res)/2;
                double num = judge(mid, dist);
                if(num<=hour){
                    end = mid-1;
                }else if(num>hour){
                    res = mid+1;
                }
            }
            return res;
            }
        return -1;
    }

    static double judge(int mid, int[] dist){
        double  ans = 0;
        for(int i = 0;i<dist.length-1;i++){
            int temp = dist[i]/mid;
            if(dist[i]%mid!=0){
                temp+=1;
            }
            ans+=temp;
        }
        ans += (dist[dist.length-1]/(mid*1.0));
        return ans;
    }

}

查看了大佬们的解析发现我想的有点复杂了,其实不需要进行分类,直接进行二分即可,下面列出来一个大佬的解析

作者:hxz1998
链接:https://leetcode-cn.com/problems/minimum-speed-to-arrive-on-time/solution/java-er-fen-fa-zhu-xing-zhu-shi-101ms528-zab8/
来源:力扣(LeetCode)

class Solution {
    public int minSpeedOnTime(int[] dist, double hour) {
        if (dist.length > Math.ceil(hour)) return -1;
        // 搜索边界
        int left = 1, right = Integer.MAX_VALUE;
        while (left < right) {
            int mid = left + (right - left) / 2;
            // 如果以 mid 速度可达,那么就尝试减小速度
            if (check(dist, hour, mid)) right = mid;
            // 否则就需要加了
            else left = mid + 1;
        }
        return left;
    }

    private boolean check(int[] dist, double hour, int speed) {
        double cnt = 0.0;
        // 对除了最后一个站点以外的时间进行向上取整累加
        for (int i = 0; i < dist.length - 1; ++i) {
            // 除法的向上取整
            cnt += (dist[i] + speed - 1) / speed;
        }
        // 加上最后一个站点所需的时间
        cnt += (double) dist[dist.length - 1] / speed;
        return cnt <= hour;
    }
}

三、5765. 跳跃游戏 VII

给你一个下标从 0 开始的二进制字符串 s 和两个整数 minJumpmaxJump 。一开始,你在下标 0 处,且该位置的值一定为 '0' 。当同时满足如下条件时,你可以从下标 i 移动到下标 j 处:

  • i + minJump <= j <= min(i + maxJump, s.length - 1)
  • s[j] == '0'.

如果你可以到达 s 的下标 s.length - 1 处,请你返回 true ,否则返回 false

在这里插入图片描述

题解一:

采用dp动态规划的方法,从前往后面遍历,到达一个0的地方的时候就查看前面在[j-maxJump,j-minJump]的数组中是否含有dp[m]=1的值,有的话将dp[j]设置为一。

但是最后一个用例没有过

在这里插入图片描述

 public static boolean canReach(String s, int minJump, int maxJump) {
        int[] dp=new int[s.length()];
        dp[0]=1;
        for(int i=1;i<s.length();i++){
            if(s.charAt(i)=='0'){
                int left=i-maxJump;
                int right=i-minJump;
                if(left<0&&right<0) continue;
                left=Math.max(left,0);
                right=Math.max(right,0);
                for(int m=left;m<=right;m++){
                    if(dp[m]==1){
                        dp[i]=1;
                        break;
                    }
                }
            }
        }
        System.out.println(Arrays.toString(dp));
        return dp[s.length()-1]==1;
    }

改进之后发现需要从前面进行扫描,不然的事件复杂度会超

 public boolean canReach(String s, int minJump, int maxJump) {
        int[] dp=new int[s.length()];
        dp[0]=1;
        for(int i=0;i<s.length();i++){
            if(dp[i]==0) continue;
            for(int j=i+minJump;j<=i+maxJump&&j<s.length()&&dp[j]==0;j++){
                dp[j]=s.charAt(j)=='0'?1:0;
            }
        }
        System.out.println(Arrays.toString(dp));
        return dp[s.length()-1]==1;
    }

之后看大佬们的解答,将我那个的遍历的判断改成了采用一个前缀树进行判断。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值