夯实算法-给定数字能组成的最大时间

139 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 27 天,点击查看活动详情

题目:LeetCode

给定一个由 4 位数字组成的数组,返回可以设置的符合 24 小时制的最大时间。

24 小时格式为 "HH:MM" ,其中 HH 在 00 到 23 之间,MM 在 00 到 59 之间。最小的 24 小时制时间是 00:00 ,而最大的是 23:59 。从 00:00 (午夜)开始算起,过得越久,时间越大。

以长度为 5 的字符串,按 "HH:MM" 格式返回答案。如果不能确定有效时间,则返回空字符串。

示例 1:

输入: arr = [1,2,3,4]
输出: "23:41"
解释: 有效的 24 小时制时间是 "12:34""12:43""13:24""13:42""14:23""14:32""21:34""21:43""23:14""23:41" 。这些时间中,"23:41" 是最大时间。

示例 2:

输入: arr = [5,5,5,5]
输出: ""
解释: 不存在有效的 24 小时制时间,因为 "55:55" 无效。

示例 3:

输入: arr = [0,0,0,0]
输出: "00:00"

示例 4:

输入: arr = [0,0,1,0]
输出: "10:00"

提示:

  • arr.length == 4
  • 0 <= arr[i] <= 9

解题思路

由题意分析知:根据数组中 >=6 的数字个数来,选择策略交换数组元素的顺序;

  • 当有3位 >=6 的数时,直接返回"",因为没有一个时间能有超过3位 >=6 的数;
  • 当有2位 >=6 的数时,这时候的第一位只能取0/1,因为第三位不能取 >=6 的数,而仅当第一位位0/1时,第二位可以取09也就是 >=6的数;
  • 当有1/0位 >=6的 数时,就可以按照第一位 02,第二位根据第一位的大小取 04 或者 09,第三位取 0~5,第四位自动确认;

代码实现

public String largestTimeFromDigits(int[] arr) {
    StringBuilder sb = new StringBuilder();
    int count = 0;
    for (int i = 0; i < 4; i++) {
        if (arr[i] > 5) {
            count++;
        }
    }
    //当有三位6或以上的数时,直接返回""
    if (count > 2) {
        return "";
    }
    //当有两位6或以上的数时,第一位只能取0/1
    if (count == 2) {
        if (find(arr, 0, 1) == -1) {
            return "";
        }
        if (find(arr, 1, 9) == -1) {
            return "";
        }
        if (find(arr, 2, 5) == -1) {
            return "";
        }
        //当有0/1位6或以上的数时
    } else {
        //第一位,从0-2的最大值
        if (find(arr, 0, 2) == -1) {
            return "";
        }
        //若第一位是2,则为剩下两位从0-3的最大值
        if (arr[0] == 2) {
            if (find(arr, 1, 3) == -1) {
                return "";
            }
            //第二位,若第一位是1/0,则为剩下两位从0-9的最大值
        } else {
            if (find(arr, 1, 9) == -1) {
                return "";
            }
        }
        //第三位,剩下两位0-5的最大值
        if (find(arr, 2, 5) == -1) {
            return "";
        }
    }
    sb.append(arr[0]);
    sb.append(arr[1]);
    sb.append(":");
    sb.append(arr[2]);
    sb.append(arr[3]);
    return sb.toString();

}
public int find(int[] arr, int index, int target) {
    int length = arr.length;
    int findNum = -1;
    int sign = -1;
    int temp;
    for (int i = index; i < length; i++) {
        if (arr[i] <= target) {
            if (arr[i] > findNum) {
                findNum = arr[i];
                sign = i;
            }
        }
    }
    if (findNum != -1) {
        temp = arr[index];
        arr[index] = findNum;
        arr[sign] = temp;
    }

    return findNum;
}

运行结果

Snipaste_2023-03-02_22-20-35.png

复杂度分析

  • 空间复杂度:O(n)O(n)
  • 时间复杂度:O(nlogn)O(nlogn)

掘金(JUEJIN)  一起分享知识, Keep Learning!