Binary Watch

题目地址:https://leetcode.com/problems/binary-watch/

A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom represent the minutes (0-59).

Each LED represents a zero or one, with the least significant bit on the right.


这里写图片描述

For example, the above binary watch reads “3:25”.

Given a non-negative integer n which represents the number of LEDs that are currently on, return all possible times the watch could represent.

Example:

Input: n = 1
Return: ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", "0:16", "0:32"]

Note:

  • The order of output does not matter.
  • The hour must not contain a leading zero, for example “01:00” is not valid, it should be “1:00”.
  • The minute must be consist of two digits and may contain a leading zero, for example “10:2” is not valid, it should be “10:02”.

题目的说给了这么一个作死的二进制表,不能直接了当地告你时间是多少,要想知道具体时间,你还得做个简单的加法。

上面一排灯,1,2,4,8四个数字表示hour,下面一排灯1,2,4,8,16,32六个数字,表示minute。

其实说来到去就是个组合问题,但是注意了,这里的组合不是边界对齐的组合,这一点会在下面的代码实现中涉及到。

hour范围[0, 1, 2, ……,10, 11]
minute范围[0, 1, 2, 3, ……, 57, 58, 59]

如果是这样的话,那肯定这些灯不能全亮,如果全亮的话,那一天(或者半天)就是15小时63分。所以要注意边界。

如果算一下很快就能得出,上面的灯最多亮3个,下排灯最多亮5个,多了的话必然是外星时间。

那既然这样,也就是说总共也只能是8个灯亮着,加上全灭那一瞬间(0:00),其实也就是9中情况。全灭特殊,直接拿出来当特例就行,剩下的只有8种情况,而且这八种情况也是可罗列出来的。

如果手动都罗列出来了,那一个switch语句就搞定了,而且效率也特高,可以说瞬间毫秒杀。

当然你也可以算一部分,比如,算一下上面灯亮1个有几种情况,2个有几种情况,3个有几种情况。同样下面灯亮1个有几种情况,2个呢,3个呢,……,8个呢?其实我就是这么干的。

剩下的工作无非就是字符转拼接了,简单的很。

因为这个题目的特殊性,正好可以用到Java中的锯齿矩阵,然后利用下标,直接拼接即可。代码实现如下:

public class BinaryWatch {
    public List<String> readBinaryWatch(int num) {
        List<String> res = new ArrayList<String>();

        if (num == 0) {
            res.add("0:00");
            return res;
        }

        if (num > 8)
            return res;

        // 上面一排灯亮的组合情况
        String[] top0 = {"0"};
        String[] top1 = {"1", "2", "4", "8"};
        String[] top2 = {"3", "5", "6", "9", "10"};
        String[] top3 = {"7", "11"};

        // 下面一排灯亮的组合情况
        String[] bottom0 = {"00"}; // length=1
        String[] bottom1 = {"01", "02", "04", "08", "16", "32"}; // length=6
        String[] bottom2 = {"03", "05", "06", "09", "10", "12", "17", "18", "20", "24", "33", "34", "36", "40", "48"}; // length=15
        String[] bottom3 = {"07", "11", "13", "14", "19", "21", "22", "25", "26", "28", "35", "37", "38", "41", "42", "44", "49", "50", "52", "56"}; //length=20
        String[] bottom4 = {"15", "23", "27", "29", "30", "39", "43", "45", "46", "51", "53", "54", "57", "58"}; // length=14
        String[] bottom5 = {"31", "47", "55", "59"}; // length=4

        String[][] top = {top0, top1, top2, top3};
        String[][] bottom = {bottom0, bottom1, bottom2, bottom3, bottom4, bottom5};

        for (int k= 0; k <= num; k++) {
            // 注意这里就是上面所提到的边界不对齐,上下灯的组合情况不一样,所以要加一个边界判断。
            if (k > 3 || num - k > 5)
                continue;
            for (int i = 0; i< top[k].length; i++) {
                for (int j = 0; j < bottom[num - k].length; j++) {
                    res.add(top[k][i] + ":" + bottom[num - k][j]);
                }
            }
        }

        return res;
    }

    public static void main(String[] args) {
        BinaryWatch watch = new BinaryWatch();
        System.out.println(watch.readBinaryWatch(7));
    }
}

我偷懒了,如果全部都列出来的话,那时间复杂度就是O(1)了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值