401. 二进制手表

本文旨在对于个人知识的梳理以及知识的分享,如果有不足的地方,欢迎大家在评论区指出

题目描述

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

例如,下面的二进制手表读取 “3:25” 。
在这里插入图片描述

给你一个整数 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
题目链接
题目分析

这道题有两种做法,我的做法在标准做法面前显得有些"丑陋",我采用了二进制枚举的方式,也就是回溯的方式,枚举小时以及分钟的所有状态,找到合法且数量恰好等于turnedOn的所有情况,时间复杂度为 O ( 2 4 ∗ 4 ∗ 2 6 ∗ 6 ) O(2^4*4*2^6*6) O(244266),标准的做法是直接枚举合法的小时和分钟,找到开启灯的数量恰好为turnedOn的所有情况,二者的本质区别在于第一种情况枚举了大量的无用状态。

解题代码

Go
标准做法

package main

var res []string

func getBit(x int) int {
    res := 0
    for x != 0 {
        res += 1
        x -= (x&-x)
    }
    return res
}

func readBinaryWatch(turnedOn int) []string {
    res = make([]string, 0)
    for h:=0; h<12; h++ {
        for m:=0; m<60; m++ {
            if getBit(h) + getBit(m) == turnedOn {
                res = append(res, fmt.Sprintf("%d:%02d", h, m))
            }
        }
    }
    return res
}

个人解法

package main

var hour = []int{1, 2, 4, 8}
var minute = []int{1, 2, 4, 8, 16, 32}
var res []string

func readBinaryWatch(turnedOn int) []string {
	res = make([]string, 0)
	for i := 0; i < 1<<len(hour); i++ {
		hourNum, curHour := 0, 0
		for j := 0; j < len(hour); j++ {
			if ((i >> j) & 1) == 1 {
				hourNum += 1
				curHour += hour[j]
			}
		}
		if hourNum > turnedOn || curHour > 11 {
			continue
		}

		for m := 0; m < 1<<len(minute); m++ {
			minuteNum, curMinute := 0, 0
			for n := 0; n < len(minute); n++ {
				if ((m>>n)&1) == 1 {
					minuteNum += 1
					curMinute += minute[n]
				}
			}
			if minuteNum > turnedOn-hourNum || curMinute > 59 {
				continue
			}
			if minuteNum + hourNum == turnedOn {
				res = append(res, fmt.Sprintf("%d:%02d", curHour, curMinute))
			}
		}
	}
	return res
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值