跳转至

401. 二进制手表

题目描述

二进制手表顶部有 4 个 LED 代表 小时(0-11),底部的 6 个 LED 代表 分钟(0-59)。每个 LED 代表一个 0 或 1,最低位在右侧。

  • 例如,下面的二进制手表读取 "4:51"

给你一个整数 turnedOn ,表示当前亮着的 LED 的数量,返回二进制手表可以表示的所有可能时间。你可以 按任意顺序 返回答案。

小时不会以零开头:

  • 例如,"01:00" 是无效的时间,正确的写法应该是 "1:00"

分钟必须由两位数组成,可能会以零开头:

  • 例如,"10:2" 是无效的时间,正确的写法应该是 "10:02"

 

示例 1:

输入:turnedOn = 1
输出:["0:01","0:02","0:04","0:08","0:16","0:32","1:00","2:00","4:00","8:00"]

示例 2:

输入:turnedOn = 9
输出:[]

 

提示:

  • 0 <= turnedOn <= 10

解法

方法一:枚举组合

题目可以转换为求 \(i \in [0, 12)\)\(j \in [0, 60)\) 的所有可能组合。

合法组合需要满足的条件是 \(i\) 的二进制形式中 1 的个数加上 \(j\) 的二进制形式中 1 的个数,结果等于 \(\textit{turnedOn}\)

时间复杂度 \(O(1)\),空间复杂度 \(O(1)\)

1
2
3
4
5
6
7
8
class Solution:
    def readBinaryWatch(self, turnedOn: int) -> List[str]:
        return [
            '{:d}:{:02d}'.format(i, j)
            for i in range(12)
            for j in range(60)
            if (bin(i) + bin(j)).count('1') == turnedOn
        ]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Solution {
    public List<String> readBinaryWatch(int turnedOn) {
        List<String> ans = new ArrayList<>();
        for (int i = 0; i < 12; ++i) {
            for (int j = 0; j < 60; ++j) {
                if (Integer.bitCount(i) + Integer.bitCount(j) == turnedOn) {
                    ans.add(String.format("%d:%02d", i, j));
                }
            }
        }
        return ans;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Solution {
public:
    vector<string> readBinaryWatch(int turnedOn) {
        vector<string> ans;
        for (int i = 0; i < 12; ++i) {
            for (int j = 0; j < 60; ++j) {
                if (__builtin_popcount(i) + __builtin_popcount(j) == turnedOn) {
                    ans.push_back(to_string(i) + ":" + (j < 10 ? "0" : "") + to_string(j));
                }
            }
        }
        return ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
func readBinaryWatch(turnedOn int) []string {
    var ans []string
    for i := 0; i < 12; i++ {
        for j := 0; j < 60; j++ {
            if bits.OnesCount(uint(i))+bits.OnesCount(uint(j)) == turnedOn {
                ans = append(ans, fmt.Sprintf("%d:%02d", i, j))
            }
        }
    }
    return ans
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
function readBinaryWatch(turnedOn: number): string[] {
    const ans: string[] = [];

    for (let i = 0; i < 12; ++i) {
        for (let j = 0; j < 60; ++j) {
            if (bitCount(i) + bitCount(j) === turnedOn) {
                ans.push(`${i}:${j.toString().padStart(2, '0')}`);
            }
        }
    }

    return ans;
}

function bitCount(i: number): number {
    i = i - ((i >>> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
    i = (i + (i >>> 4)) & 0x0f0f0f0f;
    i = i + (i >>> 8);
    i = i + (i >>> 16);
    return i & 0x3f;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
impl Solution {
    pub fn read_binary_watch(turned_on: i32) -> Vec<String> {
        let mut ans: Vec<String> = Vec::new();

        for i in 0u32..12 {
            for j in 0u32..60 {
                if (i.count_ones() + j.count_ones()) as i32 == turned_on {
                    ans.push(format!("{}:{:02}", i, j));
                }
            }
        }

        ans
    }
}

方法二:二进制枚举

我们可以利用 \(10\) 个二进制位表示手表,其中前 \(4\) 位代表小时,后 \(6\) 位代表分钟。枚举 \([0, 2^{10})\) 中的每个数,判断其二进制表示中 1 的个数是否等于 \(\textit{turnedOn}\),如果是,则将其转换为时间格式加入答案中。

时间复杂度 \(O(1)\),空间复杂度 \(O(1)\)

1
2
3
4
5
6
7
8
class Solution:
    def readBinaryWatch(self, turnedOn: int) -> List[str]:
        ans = []
        for i in range(1 << 10):
            h, m = i >> 6, i & 0b111111
            if h < 12 and m < 60 and i.bit_count() == turnedOn:
                ans.append('{:d}:{:02d}'.format(h, m))
        return ans
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution {
    public List<String> readBinaryWatch(int turnedOn) {
        List<String> ans = new ArrayList<>();
        for (int i = 0; i < 1 << 10; ++i) {
            int h = i >> 6, m = i & 0b111111;
            if (h < 12 && m < 60 && Integer.bitCount(i) == turnedOn) {
                ans.add(String.format("%d:%02d", h, m));
            }
        }
        return ans;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Solution {
public:
    vector<string> readBinaryWatch(int turnedOn) {
        vector<string> ans;
        for (int i = 0; i < 1 << 10; ++i) {
            int h = i >> 6, m = i & 0b111111;
            if (h < 12 && m < 60 && __builtin_popcount(i) == turnedOn) {
                ans.push_back(to_string(h) + ":" + (m < 10 ? "0" : "") + to_string(m));
            }
        }
        return ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
func readBinaryWatch(turnedOn int) []string {
    var ans []string
    for i := 0; i < 1<<10; i++ {
        h, m := i>>6, i&0b111111
        if h < 12 && m < 60 && bits.OnesCount(uint(i)) == turnedOn {
            ans = append(ans, fmt.Sprintf("%d:%02d", h, m))
        }
    }
    return ans
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function readBinaryWatch(turnedOn: number): string[] {
    const ans: string[] = [];

    for (let i = 0; i < 1 << 10; ++i) {
        const h = i >> 6;
        const m = i & 0b111111;

        if (h < 12 && m < 60 && bitCount(i) === turnedOn) {
            ans.push(`${h}:${m < 10 ? '0' : ''}${m}`);
        }
    }

    return ans;
}

function bitCount(i: number): number {
    i = i - ((i >>> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
    i = (i + (i >>> 4)) & 0x0f0f0f0f;
    i = i + (i >>> 8);
    i = i + (i >>> 16);
    return i & 0x3f;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
impl Solution {
    pub fn read_binary_watch(turned_on: i32) -> Vec<String> {
        let mut ans: Vec<String> = Vec::new();

        for i in 0u32..(1 << 10) {
            let h = i >> 6;
            let m = i & 0b111111;

            if h < 12 && m < 60 && i.count_ones() as i32 == turned_on {
                ans.push(format!("{}:{:02}", h, m));
            }
        }

        ans
    }
}

评论