从字符串

时间:2018-02-18 05:06:34

标签: java

我最近在面试准备中得到了与此类似的任务,只有40分钟才能完成。我知道我可以通过条件陈述来强制它,但由于对第一小时和分钟位置的限制减慢了我的速度,它开始变得有点复杂。我在这里遗漏了什么,有更简单,更快捷的方法吗?我总是对自己处理字符串和排列的能力充满信心,但现在我没有时间完成这项任务让我想知道我是否真的达到了最近毕业生的入门级工作标准。

任务:

使用给予方法的字符串中提供的这些数字的某些排列,可以显示下一个最早的时间是什么?

Class Solution {public String solution(String S); }

编写一个函数,给定一个非空字符串S,格式为“HH:MM”格式,返回相同格式的字符串,指定给定时间后第一次可以用数字的排列表示S. 例如,给定“11:10”,您的函数应返回“01:11”;对于“23:58”,结果应该是“23:58”(因为在那种情况下只有1种可能的排列)。

4 个答案:

答案 0 :(得分:1)

  1. 交换分钟ex(35-> 53),如果在交换时分钟更大并且< 60你完成了
  2. 如果分钟不大,请查看下一个最大的小时(前11 - > 12)模数24
  3. 检查您是否可以使用给定的数字进行下一个小时(12)
  4. 如果是,则使用剩余数字创建最小的分钟时间,确保分钟有效,即< 60,否则增加小时并再试一次
  5. 如果你开始的时间与你开始的时间相同,那么返回相同的排列,因为没有答案
  6. 这是我提出的pusedocode,如果您发现任何错误,请随时指出它们。顺便说一句非常有趣的问题

    这是我的解决方案,我在这个问题上玩得很开心

    public class Main {
    
        public static String nextTime(String s) {
            int hours;
            if (s.charAt(3) < s.charAt(4) && s.charAt(4) < '6')
                return s.substring(0, 3) + s.charAt(4) + s.charAt(3);
            hours = Integer.parseInt(s.substring(0, 2));
            int tempHours = hours + 1;
            while (tempHours % 24 != hours) {
                tempHours %= 24;
                String h = String.format("%02d", tempHours);
                String minutes = s;
                for (int i = 0; i < s.length(); i++) {
                    if (h.charAt(0) == s.charAt(i)) {
                        minutes = s.substring(0, i) + s.substring(i + 1);
                        break;
                    }
                }
    
                for (int i = 0; i < minutes.length(); i++) {
                    if (h.charAt(1) == minutes.charAt(i)) {
                        minutes = minutes.substring(0, i) + minutes.substring(i + 1);
                        break;
                    }
                }
    
                if (minutes.length() > 3) {
                    tempHours++;
                    continue;
                }
    
                for (int i = 0; i < minutes.length(); i++) {
                    if (':' == minutes.charAt(i)) {
                        minutes = minutes.substring(0, i) + minutes.substring(i + 1);
                        break;
                    }
                }
    
                for (int i = 0; i < s.length(); i++) {
                    if (s.charAt(i) != h.charAt(0) && h.charAt(1) != s.charAt(i) && s.charAt(i) != ':') {
                        minutes += s.charAt(i);
                    }
                }
    
                if (minutes.charAt(0) < minutes.charAt(1) && Integer.parseInt(minutes) < 60) {
                    return h + ":" + minutes;
                } else if (minutes.charAt(1) < '6') {
                    return h + ":" + minutes.charAt(1) + minutes.charAt(0);
                }
    
                tempHours++;
            }
            return s;
        }
    
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            System.out.println(nextTime(in.next()));
            in.close();
        }
    

答案 1 :(得分:1)

我可能会遗漏一些明显的东西,但为什么不呢

  • 从提供的时间开始。
  • 计算+1分钟,直到你再次到达同一时间。
  • 第一次返回与所提供时间相同的数字。

答案 2 :(得分:1)

最有效的方法是确定性方法,您可以根据数字创建时间组合。由于时间只有4位数,最大组合为4! = 24.该算法最多可创建24个组合(递归),但会短路并且只能持续有效时间的建筑组合。因此,实际组合数通常小于24.

给定(最多24个)组合,然后按时间排序。下一次只是给定时间后排序中的下一个元素。

<强>算法:

输入:有效时间字符串 T
输出:输入时间 N

后的下一次

创建一个空集(用于存储有效时间) S
创建 T 有效组合并添加到 S
S 转换为列表 L
排序 L
确定 T L 中的指数 I
如果尺寸(L) == 1则 N = T
否则 N = L 中的元素,索引 I + 1 (模数列表大小)

代码:

public class NextTime {

public static void main(String[] args) {

    String time = "12:12";
    System.out.println("Starting time="+time);
    System.out.println("Next time="+getNextTime(time));
}

static Set<Integer> times = new HashSet<>();

private static String getNextTime(String time) {
    // Create a list with the 4 digits (strip out the ':')
    List<String> digits = Arrays.asList(time.split("")).stream().filter(d -> !d.equals(":"))
            .collect(Collectors.toList());
    // Build up the set of maximum 24 times
    timeCombinations(digits, 0, "");
    // Sort the list of times (which are integers representing minutes)
    List<Integer> sortedTimeList = times.stream().sorted().collect(Collectors.toList());
    // Find the next index immediately after the current time
    int newIndex = 0;
    if (sortedTimeList.size() > 1) {
        int currentTime = Integer.valueOf(time.substring(0, 2)) * 60 + Integer.valueOf(time.substring(3, 5));
        int listPosition = sortedTimeList.indexOf(currentTime);
        newIndex = (listPosition + 1) % times.size();
    }
    // Turn the time back into a string
    String newTimeString = String.format("%02d:%02d", sortedTimeList.get(newIndex)/60, sortedTimeList.get(newIndex)%60);
    return newTimeString;
}

private static void timeCombinations(List<String> digits, int depth, String result) {
    if (depth == 4) {
        // You have a valid time; Convert time string like 1234 to minutes
        int minutes = Integer.valueOf(result.substring(0, 2)) * 60 + Integer.valueOf(result.substring(2, 4));
        times.add(minutes);
    } else {
        for (int d = 0; d < digits.size(); d++) {
            int c = Integer.valueOf(digits.get(d)).intValue();
            // Validation rule for the first digit of the hour
            if (depth == 0 && c > 2)
                continue;
            // Validation rule for the first digit of the minutes
            if (depth == 2 && c > 5)
                continue;
            List<String> digitsClone = new ArrayList<>(digits);
            String resultClone = new String(result) + digitsClone.get(d);
            // Validation rule for the complete hour
            if (depth == 1 && Integer.valueOf(resultClone).intValue() > 23)
                continue;
            digitsClone.remove(d);
            timeCombinations(digitsClone, depth + 1, resultClone);
        }
    }
}

}

答案 3 :(得分:-1)

不应按升序对这4位数进行排序,并将其格式化为HH:MM应该会产生预期的输出吗?