题目
949. 给定数字能组成的最大时间 - 力扣(LeetCode)
思路
最直接的思路是:从大到小尝试所有可能的排列,找到第一个能组成有效时间的排列。
具体步骤:
- 将数字按降序排序,得到字典序最大的排列
- 依次尝试每个排列:
- 检查前两位是否能组成有效的小时(<24)
- 检查后两位是否能组成有效的分钟(<60)
- 一旦找到符合条件的排列,立即返回对应的时间字符串
- 如果尝试完所有排列都没有找到有效时间,返回空字符串
过程
假设输入是 A = [1, 2, 3, 4],我们要找出能组成的最大时间。
步骤 1: 按降序排序
sort(A.begin(), A.end(), greater<int>());
排序后 A = [4, 3, 2, 1]
步骤 2: 开始循环检查每个排列
第一次迭代:
当前排列: [4, 3, 2, 1]
检查是否是有效时间:
- 小时部分: A[0] = 4, A[1] = 3 => 小时 = 43
- 43 > 23,不是有效小时
- 条件 ((A[0] == 2 && A[1] < 4) || A[0] < 2) 不满足
- 不是有效时间,继续下一个排列
第二次迭代:
调用 prev_permutation(A.begin(), A.end())
新排列: [4, 3, 1, 2]
检查是否是有效时间:
- 小时部分: A[0] = 4, A[1] = 3 => 小时 = 43
- 43 > 23,不是有效小时
- 不是有效时间,继续
第三次迭代:
新排列: [4, 2, 3, 1]
检查是否是有效时间:
- 小时部分: A[0] = 4, A[1] = 2 => 小时 = 42
- 42 > 23,不是有效小时
不是有效时间,继续
... (继续检查更多排列)
第十三次迭代:
新排列: [2, 3, 4, 1]
检查是否是有效时间:
- 小时部分: A[0] = 2, A[1] = 3 => 小时 = 23
- 23 < 24,是有效小时
- 分钟部分: A[2] = 4, A[3] = 1 => 分钟 = 41
- 41 < 60,是有效分钟
是有效时间!构建时间字符串:
- s = "2341"
- 插入冒号: s = "23:41"
- 返回 "23:41"
最终结果
最大有效时间是 "23:41"
读者可能出现的错误写法
class Solution {
public:string largestTimeFromDigits(vector<int>& arr) {//先进行降序排列sort(arr.begin(),arr.end(),greate<int>());do{if(arr[0] == 2 && arr[1]<=4 || arr[0]<2){if(arr[2]<6){string s = "";for(int i = 0; i<4;i++){s += arr[i].to_string();}return s;}}}while(prev_perm(arr.begin(),arr.end()));}
};
- 语法错误:greate<int>() 应该是 greater<int>()
- 函数名错误:prev_perm 应该是 prev_permutation
- 方法调用错误:arr[i].to_string() 不正确,因为 arr[i] 是 int 类型,没有 to_string() 方法。应该使用 s += ('0' + arr[i]) 或 s += to_string(arr[i])
- 缺少冒号插入:时间格式需要在中间插入冒号,如 "23:41"
- 条件判断括号问题:arr[0] == 2 && arr[1]<=4 || arr[0]<2 应该加括号明确优先级:((arr[0] == 2 && arr[1]<4) || arr[0]<2)
- 缺少返回值:如果没有找到有效时间,应该返回空字符串
- 小时判断条件:当小时第一位是2时,第二位应该 < 4 (不是<=4)
正确写法
class Solution {
public:string largestTimeFromDigits(vector<int>& arr) {//先进行降序排列sort(arr.begin(),arr.end(),greater<int>());do{if((arr[0] == 2 && arr[1]<4) || arr[0]<2){if(arr[2]<6){string s = "";for(int i = 0; i<4;i++){s += ('0' + arr[i]);}s.insert(2,":");return s;}}}while(prev_permutation(arr.begin(),arr.end()));return "";}
};
