题目: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
解题思路
对于一个24小时格式的时间 HH:MM, 这里要明确两点:
- HH值的范围为[0,23], 即0<=HH<=23;
- MM值的范围为[0,59], 即0<=MM<=59; 所以, 明确了HH和MM的范围, 这里就用不着全排列了找所有的可能组合了, 只需要在范围内找HH和MM的值即可。 步骤如下:
- 对arr数组进行排序;
- 用left和right双指针从左往右遍历数组arr: --(1) 以左指针left指向的值arr[left]为十位数, 右指针right指向的值arr[right]为个位数进行组合, 寻找小于等于23, 并使HH可能最大的值;
- 遍历一遍数组arr, 统计大于等于6的数字的个数记为maxThanSix;
- 若maxThanSix小于2, 则: --(1) 以右指针right指向的值arr[right]为十位数, 左指针left指向的值arr[left]为个位数进行组合, 寻找小于等于23, 并使HH可能最大的值;
- 若没有找到一个组合使0<=HH<=23, 则直接返回空字符串;
- 将剩下两个没有使用的数字进行组合, 寻找小于等于59, 并使MM可能最大的组合;
- 若没有找到一个组合使0<=MM<=59, 则直接返回空字符串;
- 将HH和MM拼接成字符串, 这里需要注意, 当HH和MM不足两位数时, 前面用0补足.
由题意分析知:根据数组中 >=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;
}
运行结果
复杂度分析
- 空间复杂度:
- 时间复杂度:
在掘金(JUEJIN) 一起分享知识, Keep Learning!