401. Binary Watch

Description

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.

401. Binary Watch_第1张图片
image

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

Solution

Backtrack

跟getCombinations一个思路,注意hour和min都有上限。

class Solution {
    public List readBinaryWatch(int num) {
        List times = new ArrayList<>();
        if (num > 8) {
            return times;
        }
        
        for (int i = 0; i <= 3; ++i) {
            List hours = getBinaryList(i, 4, 0);
            List mins = getBinaryList(num - i, 6, 0);
            
            for (int hour : hours) {
                if (hour > 11) {    // don't forget overflow
                    break;
                }
                
                for (int min : mins) {
                    if (min > 59) {
                        break;
                    }
                    times.add(hour + (min < 10 ? ":0" : ":") + min);
                }
            }
        }
        
        return times;
    }
    
    public List getBinaryList(int i, int n, int sum) {
        if (i < 0 || i > n) {
            return new ArrayList<>();
        }
        
        if (i == 0) {
            List result = new ArrayList<>();
            result.add(sum);
            return result;
        }
        
        List result = getBinaryList(i, n - 1, sum);
        int ithBinary = (int) Math.pow(2, n - 1);
        result.addAll(getBinaryList(i - 1, n - 1, sum + ithBinary));
        
        return result;
    }
}

Optimised: Bit operation, time O(1), space O(1)

其实如果最优解是上面那个的话,这道题就不应该是easy难度了。所以应该使用下面的Optimised解法。
感觉用二进制操作还是挺优雅的哈。这道题目给我的启发是,有时不必直接把所求的集合直接算出来,而是可以从一个大集合中筛选出所求解。

class Solution {
    public List readBinaryWatch(int num) {
        List times = new ArrayList();
        
        for (int h = 0; h < 12; ++h) {
            for (int m = 0; m < 60; ++m) {
                if (getDigits(h << 6 | m) != num) {
                    continue;
                }
                times.add(h + (m < 10 ? ":0" : ":") + m);
            }
        }
        
        return times;
    }
    
    public int getDigits(int n) {
        int digits = 0;
        
        for (int i = 0; i < 32; ++i) {
            digits += n & 1;
            n >>= 1;
        }
        
        return digits;
    }
}

你可能感兴趣的:(401. Binary Watch)