Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LeetCode 401. 二进制手表 #22

Open
Chocolate1999 opened this issue Sep 15, 2020 · 0 comments
Open

LeetCode 401. 二进制手表 #22

Chocolate1999 opened this issue Sep 15, 2020 · 0 comments
Labels
递归与回溯 LeetCode 递归与回溯专栏

Comments

@Chocolate1999
Copy link
Owner

仰望星空的人,不应该被嘲笑

题目描述

二进制手表顶部有 4 个 LED 代表 小时(0-11),底部的 6 个 LED 代表 分钟(0-59)

每个 LED 代表一个 0 或 1,最低位在右侧。

例如,上面的二进制手表读取 “3:25”。

给定一个非负整数 n 代表当前 LED 亮着的数量,返回所有可能的时间。

示例:

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

提示:

输出的顺序没有要求。
小时不会以零开头,比如 “01:00 是不允许的,应为 “1:00”。
分钟必须由两位数组成,可能会以零开头,比如 “10:2 是无效的,应为 “10:02”。
超过表示范围(小时 0-11,分钟 0-59)的数据将会被舍弃,也就是说不会出现 "13:00", "0:61" 等时间。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-watch
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

回溯算法,我的解法类似于全排列做法,将10个小灯泡进行排列组合,然后根据 01 来判断灯泡是否亮,如果亮了,加上对应二进制,然后将 0-3分给小时来计算,将 4-9分给分钟来计算,但是要考虑一下,就是可能会出现重复情况,于是用 Set数据结构维护一下就好了。

var readBinaryWatch = function(num) {
    let res = new Set();
    let vis = new Array(10).fill(0)
    let check = (hour,minutes) => {
      if(hour>=0 && hour<=11 && minutes>=0 && minutes<=59) return true;
      return false;
    }
    let dfs = (t,vis) => {
      if(t==0){
        let hour = vis[0]*1 + vis[1]*2 + vis[2]*4 + vis[3]*8;
        let minutes = vis[4]*1 + vis[5]*2 + vis[6]*4 + vis[7]*8 + vis[8]*16 + vis[9]*32;
        if(check(hour,minutes)){
          let tmp = `${hour}:${minutes >= 10? minutes: '0'+minutes}`;
          res.add(tmp);
        }
      }
      for(let i=0;i<10;i++){
        if(vis[i]) continue;
        vis[i] = 1;
        dfs(t-1,vis);
        vis[i] = 0;
      }
    }
    dfs(num,vis);
    return [...res];
};

补充,后面看到有大佬这样做,进行了去重操作,关键点在回溯 for循环那里。其实这个相当于全排列了。

var readBinaryWatch = function(num) {
    let res = [];
    let vis = new Array(10).fill(0)
    let check = (hour,minutes) => {
      if(hour>=0 && hour<=11 && minutes>=0 && minutes<=59) return true;
      return false;
    }
    let dfs = (t,cnt,vis) => {
      if(t==0){
        let hour = vis[0]*1 + vis[1]*2 + vis[2]*4 + vis[3]*8;
        let minutes = vis[4]*1 + vis[5]*2 + vis[6]*4 + vis[7]*8 + vis[8]*16 + vis[9]*32;
        if(check(hour,minutes)){
          let tmp = `${hour}:${minutes >= 10? minutes: '0'+minutes}`;
          res.push(tmp);
        }
        return;
      }
      for(let i=cnt;i<=10-t;i++){
        if(vis[i]) continue;
        vis[i] = 1;
        dfs(t-1,i+1,vis);
        vis[i] = 0;
      }
    }
    dfs(num,0,vis);
    return res;
};

最后

文章产出不易,还望各位小伙伴们支持一波!

往期精选:

小狮子前端の笔记仓库

访问超逸の博客,方便小伙伴阅读玩耍~

学如逆水行舟,不进则退
@Chocolate1999 Chocolate1999 added the 递归与回溯 LeetCode 递归与回溯专栏 label Sep 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
递归与回溯 LeetCode 递归与回溯专栏
Projects
None yet
Development

No branches or pull requests

1 participant