leetcode-pp / 91alg-11-daily-check

第十一期打卡
3 stars 0 forks source link

【Day 34 】2023-07-13 - 1904. 你完成的完整对局数 #36

Open azl397985856 opened 1 year ago

azl397985856 commented 1 year ago

1904. 你完成的完整对局数

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/the-number-of-full-rounds-you-have-played/

前置知识

给你两个字符串 startTime 和 finishTime ,均符合 "HH:MM" 格式,分别表示你 进入 和 退出 游戏的确切时间,请计算在整个游戏会话期间,你完成的 完整对局的对局数 。

例如,如果 startTime = "05:20" 且 finishTime = "05:59" ,这意味着你仅仅完成从 05:30 到 05:45 这一个完整对局。而你没有完成从 05:15 到 05:30 的完整对局,因为你是在对局开始后进入的游戏;同时,你也没有完成从 05:45 到 06:00 的完整对局,因为你是在对局结束前退出的游戏。

如果 finishTime 早于 startTime ,这表示你玩了个通宵(也就是从 startTime 到午夜,再从午夜到 finishTime)。

假设你是从 startTime 进入游戏,并在 finishTime 退出游戏,请计算并返回你完成的 完整对局的对局数 。

 

示例 1:

输入:startTime = "12:01", finishTime = "12:44" 输出:1 解释:你完成了从 12:15 到 12:30 的一个完整对局。 你没有完成从 12:00 到 12:15 的完整对局,因为你是在对局开始后的 12:01 进入的游戏。 你没有完成从 12:30 到 12:45 的完整对局,因为你是在对局结束前的 12:44 退出的游戏。

示例 2:

输入:startTime = "20:00", finishTime = "06:00" 输出:40 解释:你完成了从 20:00 到 00:00 的 16 个完整的对局,以及从 00:00 到 06:00 的 24 个完整的对局。 16 + 24 = 40

示例 3:

输入:startTime = "00:00", finishTime = "23:59" 输出:95 解释:除最后一个小时你只完成了 3 个完整对局外,其余每个小时均完成了 4 场完整对局。

 

提示:

startTime 和 finishTime 的格式为 HH:MM 00 <= HH <= 23 00 <= MM <= 59 startTime 和 finishTime 不相等

HuiyingC commented 1 year ago

Intuition

Code

def numberOfRounds(self, loginTime, logoutTime):
    hs, ms = (int(x) for x in loginTime.split(":"))
    ts = 60 * hs + ms
    hf, mf = (int(x) for x in logoutTime.split(":"))
    tf = 60 * hf + mf
    if 0 <= tf - ts < 15: return 0 # edge case 

    # tf//15 -> convert logout time to the same / earlier 15 min count, we are effectively getting the floor.
    # (ts+14)//15 -> convert login time to the same / later 15 min count, we are effectively getting the ceiling.
    # (ts>tf)*96 -> if login time is later than logout time, add 4 quarters per hour * 24 hours = 96 counts, otherwise add 0.
    return tf//15 - (ts+14)//15 + (ts>tf)*96

Complexity Analysis
Time complexity: O(1)
Space complexity: O(1)

zhaoygcq commented 1 year ago

思路

分割开始/结束时间;通过分钟数确定偏移量offset;通过小时决定整体的数量count。 最后的结果为 count - offset

代码

/**
 * @param {string} loginTime
 * @param {string} logoutTime
 * @return {number}
 */
var numberOfRounds = function(loginTime, logoutTime) {
    let offset = 0;
    let count = 0;
    let startArr = loginTime.split(":").map(item => Number(item));
    let startTime = startArr[0];
    let offsetTime = startArr[1];
    offset += findStartOffset(offsetTime);
    let endArr = logoutTime.split(":").map(item => Number(item));
    let endTime = endArr[0];
    offsetTime = endArr[1];
    offset -= findEndOffset(offsetTime);
    if(endTime != startTime) {
        if(endTime < startTime) {
            endTime += 24;
        }
    } else {
        if(endArr[1] < startArr[1]) {
            endTime += 24;
        }
    }

    count += (endTime - startTime) * 4 - offset
    console.log(offset, "==", count)
    return count >= 0 ? count : 0;
};

function findStartOffset(offsetTime) {
    const offsetArr = [0, 15, 30, 45];
    for(let i = 0; i < offsetArr.length; i++) {
        if(offsetTime <= offsetArr[i]) {
            return i;
        }
    }
    return 4;
}

function findEndOffset(offsetTime) {
    const offsetArr = [0, 15, 30, 45];
    for(let i = offsetArr.length - 1; i >= 0; i--) {
        if(offsetTime >= offsetArr[i]) {
            return i;
        }
    }
}

复杂度分析

GuitarYs commented 1 year ago
class Solution(object):
    def numberOfRounds(self, loginTime, logoutTime):
        """
        :type loginTime: str
        :type logoutTime: str
        :rtype: int
        """
        start_hour, start_minute = map(int, loginTime.split(":"))
        end_hour, end_minute = map(int, logoutTime.split(":"))

        if end_hour < start_hour or (end_hour == start_hour and end_minute < start_minute):
            end_hour += 24

        start_rounded_minute = ((start_minute + 14) // 15) * 15
        end_rounded_minute = (end_minute // 15) * 15

        start_time = start_hour * 60 + start_rounded_minute
        end_time = end_hour * 60 + end_rounded_minute

        return max(0, (end_time - start_time) // 15)
Diana21170648 commented 1 year ago

思路

开始时间以右边的结束时间为主,结束时间以左边的

代码

class Solution:
    def numberOfRounds(self, startTime:str, finishTime:str)->int:
        sh,sm=map(int,startTime.split(":"))
        eh,em=map(int,finishTime.split(":"))
        count_jinwei=0#看天数是否加1
        #转换成分钟,看时间是否进位
        if sh*60+sm>eh*60+em:
            count_jinwei+=1

        #处理开始时间:
        if 0<sm<=15:
            sm=15
        elif 15<sm<=30:
            sm=30
        elif 30<sm<=45:
            sm=45
        elif 45<sm<=60:
            sm=0
            sh+=1#小时进位

        #处理结束时间:
        if 0<=em<15:
            em=0
        elif 15<=em<30:
            em=15
        elif 30<=em<45:
            em=30
        elif 45<=em<60:
            em=45

        start_shijian=sh*60+sm
        end_shijian=eh*60+em
        if count_jinwei==1:
            end_shijian+=24*60
        return max(0,(end_shijian-start_shijian))//15#把时间加一起之后取整
#s=Solution()
#startTime="12:01"
#finishTime="12:46"
#print(s.numberOfRounds1904(startTime,finishTime))

复杂度分析

catkathy commented 1 year ago

思路

将登录时间和注销时间转换为分钟表示,将登录时间向上调整到下一个15分钟的间隔,将注销时间向下调整到上一个15分钟的间隔,然后计算调整后的时间之间完整的15分钟间隔的个数。

Code

class Solution:
    def numberOfRounds(self, loginTime: str, logoutTime: str) -> int:

        login_minutes = self.time_to_minutes(loginTime)
        logout_minutes = self.time_to_minutes(logoutTime)

        if logout_minutes < login_minutes:
            logout_minutes += 24 * 60

        rounded_login = self.round_up(login_minutes)
        rounded_logout = self.round_down(logout_minutes)

        # Calculate the number of rounds played
        num_rounds = max(0, (rounded_logout - rounded_login) // 15)

        return num_rounds

    def time_to_minutes(self, time_str: str) -> int:
        # Parse the hours and minutes from the time string
        hours, minutes = map(int, time_str.split(':'))
        # Convert hours to minutes and sum with minutes
        total_minutes = hours * 60 + minutes
        return total_minutes

    def round_up(self, minutes: int) -> int:
        # Round up to the next multiple of 15
        rounded_minutes = (minutes + 14) // 15 * 15
        return rounded_minutes

    def round_down(self, minutes: int) -> int:
        # Round down to the previous multiple of 15
        rounded_minutes = minutes // 15 * 15
        return rounded_minutes

复杂度分析

O(1)

jennyjgao commented 1 year ago
class Solution {
    public int numberOfRounds(String loginTime, String logoutTime) {
        // 分离hour和min
        int hourA=Integer.parseInt(loginTime.substring(0,2));
        int minA=Integer.parseInt(loginTime.substring(3,5));
        int hourB=Integer.parseInt(logoutTime.substring(0,2));
        int minB=Integer.parseInt(logoutTime.substring(3,5));
        int res=0;
        // 退出时间比登录时间小,两种情况:hour小、hour相等min小
        if(hourB<hourA||(hourA==hourB&&minA>minB)) hourB+=24;
        // 向上取整登录时间
        if(minA%15!=0){
            minA=(minA/15+1)*15;
        }
        // 向下取整退出时间
        if(minB%15!=0){
            minB=(minB/15)*15;
        }
        // hour不相同,则分别计算登录和退出两个hour中可以玩的次数,再用中间的hour数*4
        if(hourB!=hourA){
            res=(60-minA)/15;
            res+=minB/15;
            res+=(hourB-hourA-1)*4;
        }else{
            res=(minB-minA)/15;
        }
        return res>=0?res:0;
    }
}
wzbwzt commented 1 year ago

/* 思路:

复杂度: O(1) O(1) */

func numberOfRounds(loginTime string, logoutTime string) int {
    in_t := strings.Split(loginTime, ":")
    out_t := strings.Split(logoutTime, ":")
    if len(in_t) != 2 || len(out_t) != 2 {
        return 0
    }
    in_h_tmp, in_m_tmp := in_t[0], in_t[1]
    out_h_tmp, out_m_tmp := out_t[0], out_t[1]

    in_h, _ := strconv.Atoi(in_h_tmp)
    in_m, _ := strconv.Atoi(in_m_tmp)
    out_h, _ := strconv.Atoi(out_h_tmp)
    out_m, _ := strconv.Atoi(out_m_tmp)

    if in_h > out_h || (in_h == out_h && in_m > out_m) {
        out_h += 24
    }
    if in_h == out_h && in_m < out_m {
        if (in_m+15)/15*15 > out_m {
            return 0
        }
    }

    if 0 < in_m && in_m <= 15 {
        in_m = 15
    }

    if 15 < in_m && in_m <= 30 {
        in_m = 30
    }

    if 30 < in_m && in_m <= 45 {
        in_m = 45
    }

    if 45 < in_m && in_m <= 59 {
        in_m = 00
        if in_h == out_h && in_m < out_m {
            return 0
        }

        in_h++
    }

    if 0 <= out_m && out_m < 15 {
        out_m = 0
    }
    if 15 < out_m && out_m < 30 {
        out_m = 15
    }
    if 30 < out_m && out_m < 45 {
        out_m = 30
    }

    if 45 < out_m && out_m <= 59 {
        out_m = 45
    }

    offset := 0
    if out_m < in_m {
        if in_h == out_h {
            out_h += 24
        }
        offset = (in_m - out_m) / 15
        out_m = in_m
    }
    return (out_h-in_h)*4 + (out_m-in_m)/15 - offset
}
Fuku-L commented 1 year ago

代码

class Solution {
    public int numberOfRounds(String loginTime, String logoutTime) {
        int in = 60 * Integer.parseInt(loginTime.substring(0,2)) + Integer.parseInt(loginTime.substring(3,5));
        int out = 60 * Integer.parseInt(logoutTime.substring(0,2)) + Integer.parseInt(logoutTime.substring(3,5));
        if(out < in) {
            // outTime 为第二天
            out += 1440;
        }
        out = out / 15 * 15;
        return Math.max(0, (out - in)) / 15;
    }
}
SoSo1105 commented 1 year ago

思路

将开始时间和结束时间规范到标准时间

代码

class Solution:
    def numberOfRounds(self, startTime: str, finishTime: str) -> int:
        sh, sm = map(int, startTime.split(":"))
        eh, em = map(int, finishTime.split(":"))
        if 0 < sm < 15:
            sm = 15
        elif 15 < sm < 30:
            sm = 30
        elif 30 < sm < 45:
            sm = 45
        elif 45 < sm < 60:
            sm = 0
            sh += 1
        if 0 < em < 15:
            em = 0
        elif 15 < em < 30:
            em = 15
        elif 30 < em < 45:
            em = 30
        elif 45 < em < 60:
            em = 45
        st = sh * 60 + sm
        et = eh * 60 + em
        if st > et:
            et += 24 * 60
        return (et - st) // 15

复杂度分析

Moin-Jer commented 1 year ago
class Solution {
    public int numberOfRounds(String loginTime, String logoutTime) {
        String[] inTime = loginTime.split(":");
        String[] outTime = logoutTime.split(":");
        int sh = Integer.valueOf(inTime[0]);
        int sm = Integer.valueOf(inTime[1]);
        int eh = Integer.valueOf(outTime[0]);
        int em = Integer.valueOf(outTime[1]);
        if (sh * 60 + sm > eh * 60 + em) {
            eh += 24;    
        }
        if (0 < sm && sm <= 15) {
            sm = 15;
        } else if (15 < sm && sm <= 30) {
            sm = 30;
        } else if (30 < sm && sm <= 45) {
            sm = 45;
        } else if (45 < sm && sm <= 60) {
            sm = 0;
            sh += 1;
        }
        if (0 <= em && em < 15) {
            em = 0;
        } else if (15 <= em && em < 30) {
            em = 15;
        } else if (30 <= em && em < 45) {
            em = 30;
        } else if (45 <= em && em < 60) {
            em = 45;
        }
        return Math.max(0,(eh * 60 + em - sh * 60 - sm) / 15);
    }
}
mo660 commented 1 year ago

代码

class Solution {
public:
    int numberOfRounds(string loginTime, string logoutTime) {
        int start = 60 * stoi(loginTime.substr(0,2)) + stoi(loginTime.substr(3,5));
        int end = 60 * stoi(logoutTime.substr(0,2)) + stoi(logoutTime.substr(3,5));
        int res = 0;
        if (start > end)
            end += 60*24;
        end = end/15 *15;
        res = (end - start)/15;
        return res;
    }
};
Alexno1no2 commented 1 year ago
# 转换单位为分钟
# 开始小于结束,跨天,+24h处理
# 转换为单位为15分钟
# 1 整点才开始, 故向上取整
# 2 整点完成才算完成,故向下取整
# 返回求差值

class Solution:
    def numberOfRounds(self, loginTime: str, logoutTime: str) -> int:
        m1,m2 = self.toMinutes(loginTime), self.toMinutes(logoutTime)
        if m1 > m2:
            m2 += 24 * 60
        ans = math.floor(m2 / 15) - math.ceil(m1 / 15)
        if ans < 0:
            ans = 0 
        return ans

    def toMinutes(self,time):
        h, m = time.split(':')
        return int(h) * 60 + int(m)
Beanza commented 1 year ago

def numberOfRounds(self, loginTime, logoutTime): hs, ms = (int(x) for x in loginTime.split(":")) ts = 60 hs + ms hf, mf = (int(x) for x in logoutTime.split(":")) tf = 60 hf + mf if 0 <= tf - ts < 15: return 0

snmyj commented 1 year ago
class Solution {
public:
    int numberOfRounds(string loginTime, string logoutTime) {
            int start=stoi(loginTime.substr(0,2))*60+stoi(loginTime.substr(3,2));
            int end=stoi(logoutTime.substr(0,2))*60+stoi(logoutTime.substr(3,2));
            int cnt;
            if(end>start) cnt=(end-end%15)/15-(start+(15-start%15))/15;
            if(end<start) cnt=((1440-start)-(1440-start)%15)/15+(end-end%15)/15;
            return cnt;
    }
};
yetfan commented 1 year ago

代码

class Solution:
    def numberOfRounds(self, startTime: str, finishTime: str) -> int:
        t0 = 60 * int(startTime[:2]) + int(startTime[3:])
        t1 = 60 * int(finishTime[:2]) + int(finishTime[3:])
        if t1 < t0:
            t1 += 1440
        t1 = t1 // 15 * 15
        return max(0, (t1 - t0)) // 15