【LeetCode】401 Binary Watch (java實現)

原題連接

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).code

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

For example, the above binary watch reads "3:25".leetcode

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

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

題目要求

題目叫「二進制表」,顧名思義,就是用二進制的方式實現的手錶,Led燈來表示二進制,亮着表示置位1,不亮表示0。4個位表示小時,6個位表示分鐘。題目要求給定亮着的Led燈個數,求出全部能夠表示的時間列表。it

解法

解法一:輪詢遍歷法。代碼簡潔明瞭,固然,這樣的性能並很差。io

public List<String> readBinaryWatch(int num) {
    List<String> times = new ArrayList<>();
    for (int h = 0; h < 12; h++)
        for (int m = 0; m < 60; m++)
            if (Integer.bitCount(h * 64 + m) == num)
                times.add(String.format("%d:%02d", h, m));
    return times;
}

解法二:動態規劃。有n個led等,其中亮了k個時,能夠有f(n,k)種可能性。如何計算f(n,k)呢?當n=k時,n個led燈,n個都亮,很好理解,就只有1中可能。當n>k時,若是第一個燈亮,那麼就須要剩下的n-1個燈裏,有k-1個燈亮,也就是f(n-1,k-1);當第一個燈不亮,那麼就是剩下的n-1個燈裏,有k個燈亮。就這兩種可能。所以,計算f(n,k)的公式爲:
f(n,k) = 1           當n=k時
f(n,k) = f(n-1,k-1) + f(n-1,k)   當n>k時ast

// 獲取ledCnt個led燈,亮num個時,全部的可能性數字,不區分小時仍是分鐘
private List<Integer> getCombination(int ledCnt, int num) {
    // 特殊處理,當沒有led亮時
    if(num <= 0) {
        List<Integer> l = new ArrayList<Integer>();
        l.add(0);
        return l;
    }
    // 相等時,不須要再迭代處理
    if (ledCnt == num) {
        List<Integer> l = new ArrayList<Integer>();
        int data = 0;
        for (int i = 0; i < num; i++) {
            data += 1 << i;
        }
        l.add(data);
        return l;
    } else {
        List<Integer> l = new ArrayList<Integer>();
        
        if (num > 1) {
            List<Integer> subList = getCombination(ledCnt - 1, num - 1);
            Integer []a = new Integer[subList.size()];
            subList.toArray(a);
            int high = 1 << (ledCnt - 1);
            for (int i = 0; i < a.length; i++) {
                l.add(a[i] + high);
            }
        }else {
            l.add(1 << (ledCnt - 1));
        }
        
        l.addAll(getCombination(ledCnt - 1, num));
        return l;
    }
}

public List<String> readBinaryWatch(int num) {
    int hourCnt = 4;
    int minCnt = 6;
    List<String> res = new ArrayList<String>();
    
	// 小時和分鐘能亮燈個數的全部可能性
    for (int i = num > minCnt? (num - minCnt) : 0; i <= Math.min(hourCnt, num); i++) {
        List<Integer> hourList = getCombination(hourCnt, i);
        List<Integer> minList = getCombination(minCnt, num - i);
        for (Integer hour : hourList) {
            if (hour >= 12) {
                continue;
            }
            for (Integer min : minList) {
                if (min <= 59) {
                    res.add(String.format("%d:%02d", hour, min));
                }
            }
        }
    }
    return res;
}
相關文章
相關標籤/搜索