【亡羊补牢】挑战数据结构与算法 第21期 LeetCode 401. 二进制手表(递归与回溯)

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

题目描述

二进制手表顶部有 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;
};

最后

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

往期精选:

小狮子前端の笔记仓库

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

学如逆水行舟,不进则退

猜你喜欢

转载自blog.csdn.net/weixin_42429718/article/details/108601947