LeetCode 401. Binary Watch

A binary watch has 4 LEDs on the top to represent the hours (0-11), and 6 LEDs on the bottom to represent the minutes (0-59). Each LED represents a zero or one, with the least significant bit on the right.

  • For example, the below binary watch reads "4:51".

Given an integer turnedOn which represents the number of LEDs that are currently on (ignoring the PM), return all possible times the watch could represent. You may return the answer in any order.

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".

Example 1:

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

Example 2:

Input: turnedOn = 9
Output: []

Constraints:

  • 0 <= turnedOn <= 10

 这题是说用二进制来表示时间,要求如果整体的表示有n个1,有几种可能的组合。

就,拿到题就头大了。看了答案,一个比较简单的brute force的解法就是遍历所有的时间组合,计里面算一共有多少个1,如果h和m加起来1的个数为给定的数量,就加入result list。

class Solution {
    public List<String> readBinaryWatch(int turnedOn) {
        List<String> result = new ArrayList<>();
        for (int h = 0; h < 12; h++) {
            for (int m = 0; m < 60; m++) {
                if (Integer.bitCount(h) + Integer.bitCount(m) == turnedOn) {
                    result.add(h + ":" + ((m < 10) ? "0" : "") + m);
                }
            }
        }
        return result;
    }
}

 还有人说真正的industrial做法并不会搞什么高大上的东西,直接写死就好了……

 

- LeetCode

然后就是最令人头大的backtracking做法,着实是不会啊。我参考的是这篇:- LeetCode 

首先先用两个数组保存所有hour和min每个bit代表的数字(1/2/4/8...),于是就相当于从这些数字里面加起来凑成最后的hour和min。在一个for loop里面把turnedOn分为两个部分,一部分是hour(h),一部分是min(m),h + m = turnedOn。需要对hour和min分别生成 1的个数为h和m的数字,这里用一个helper来完成这个操作。拿到了hour和min对应的数字,只需要把他们都凑一起就行了。

在helper里,我们把candidate数字的数组、需要的1的个数、当前遍历到的position、这个数字的十进制表示、和一个用来存放满足1的个数的条件的数字的list。如果当前已经不需要新的1了,就把当前的十进制表示放进list。否则,我们就需要从当前的position开始,把当前position代表的那个数字设为1,直到设到了指定个数的1为止,就是前面的停止条件了。

这里我还额外加了一个参数,就是最大的数字限制,这样加入list的就只有满足条件的数字了。

理解的还不是很深刻,都是强行解释的答案……交了以后发现并没有比brute force快多少

class Solution {
    public List<String> readBinaryWatch(int turnedOn) {
        List<String> result = new ArrayList<>();
        int[] hours = new int[]{8, 4, 2, 1};
        int[] mins = new int[]{32, 16, 8, 4, 2, 1};

        for (int hourOne = 0; hourOne <= turnedOn; hourOne++) {
            int minOne = turnedOn - hourOne;
            System.out.println("hour: " + hourOne + ", min: " + minOne);
            System.out.println("generating hour");
            List<Integer> hourList = generateDigit(hours, hourOne, 12);
            System.out.println("generating min");
            List<Integer> minList = generateDigit(mins, minOne, 60);
            for (int hour : hourList) {
                for (int min : minList) {
                    result.add(hour + ":" + ((min < 10) ? "0" : "") + min);
                }
            }
        }
        return result;
    }

    private List<Integer> generateDigit(int[] array, int numOne, int max) {
        List<Integer> result = new ArrayList<>();
        helper(array, numOne, 0, 0, result, max);
        return result;
    }

    private void helper(int[] array, int numOne, int pos, int number, List<Integer> result, int max) {
        System.out.println(numOne + ", " + pos + ", " + number);
        if (numOne == 0) {
            if (number < max) {
                System.out.println("added: " + number);
                result.add(number);
            }
            return;
        }

        for (int i = pos; i < array.length; i++) {
            helper(array, numOne - 1, i + 1, number + array[i], result, max);
        }
    }
}

举个例子:

turnedOn = 1

hour: 0, min: 1
generating hour
0, 0, 0
added: 0
generating min
1, 0, 0
0, 1, 32
added: 32
0, 2, 16
added: 16
0, 3, 8
added: 8
0, 4, 4
added: 4
0, 5, 2
added: 2
0, 6, 1
added: 1
hour: 1, min: 0
generating hour
1, 0, 0
0, 1, 8
added: 8
0, 2, 4
added: 4
0, 3, 2
added: 2
0, 4, 1
added: 1
generating min
0, 0, 0
added: 0

turnedOn = 2

hour: 0, min: 2
generating hour
0, 0, 0
added: 0
generating min
2, 0, 0
1, 1, 32
0, 2, 48
added: 48
0, 3, 40
added: 40
0, 4, 36
added: 36
0, 5, 34
added: 34
0, 6, 33
added: 33
1, 2, 16
0, 3, 24
added: 24
0, 4, 20
added: 20
0, 5, 18
added: 18
0, 6, 17
added: 17
1, 3, 8
0, 4, 12
added: 12
0, 5, 10
added: 10
0, 6, 9
added: 9
1, 4, 4
0, 5, 6
added: 6
0, 6, 5
added: 5
1, 5, 2
0, 6, 3
added: 3
1, 6, 1
hour: 1, min: 1
generating hour
1, 0, 0
0, 1, 8
added: 8
0, 2, 4
added: 4
0, 3, 2
added: 2
0, 4, 1
added: 1
generating min
1, 0, 0
0, 1, 32
added: 32
0, 2, 16
added: 16
0, 3, 8
added: 8
0, 4, 4
added: 4
0, 5, 2
added: 2
0, 6, 1
added: 1
hour: 2, min: 0
generating hour
2, 0, 0
1, 1, 8
0, 2, 12
0, 3, 10
added: 10
0, 4, 9
added: 9
1, 2, 4
0, 3, 6
added: 6
0, 4, 5
added: 5
1, 3, 2
0, 4, 3
added: 3
1, 4, 1
generating min
0, 0, 0
added: 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值