LeetCode:二进制手表【401】

题目描述

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

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

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

给定一个非负整数 代表当前 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”。

题目分析

  这道题目标注为简单题,但感觉做起来比较费劲,虽然最后写出来了,但感觉代码很冗余。讨论有很多非常巧妙的办法,需要运用数学方法,我是绝对想不出来的。

  我的思路是这样的,题目意思是在小时数组{1,2,4,8} 和分钟数组{1,2,4,8,16,32}中一共选择N个数来组成一个时间

  那我们第一个要解决的问题是如何在一个数组中选出所有N个数的组合

  1、如何取出组合的第一个数?

  我们从左往右,首先我们将a加入tmpList(临时存储排列的线性表)中,此后再从它下一个位置开始找第二个、第三个数字,最后生成排列存储在结果中。我们再将1作为第一个元素开始处理后,赶紧把他删了,再将b加入到tmpList中,此后再从它下一个位置开始找第二个、第三个数字,最后生成排列存储在结果中....

  也就是说处理第i个位置的元素时,就要考虑到i位置的所有取值,我们在处理为a的元素后,赶紧把他删了处理为b的元素.....这样第i个位置就有所有的情况了

  

  知道这个以后,我们就可以得到在一个数组中选出所有N个数的组合。

  2、关于排列组合的一个典型的递归回溯框架是这样的

private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums){
if(tempList.size() == nums.length){
list.add(new ArrayList<>(tempList));
} else{
for(int i = 0; i < nums.length; i++){
if(tempList.contains(nums[i])) continue; // element already exists, skip
tempList.add(nums[i]);
backtrack(list, tempList, nums);
tempList.remove(tempList.size() - 1);
}
}
}

  当我们分别取出小时和分钟的各种可能情况,再次做他们的笛卡尔积,从而生产所有的时间可能。  

  很抱歉的是,这道题并不需要严格的递归回溯框架,我从而使用了简单使用了深搜。

    /**
*
* @param arr 待产生排列的数组
* @param index 位置下标
* @param cur 已经找了CUR个数
* @param n 一共要找N个数
* @param val 已经找到的数的和
* @param res 当招够N个数后把他加入res表中
* @param max val不能超过多少
*/
private void helper(int[] arr,int index,int cur,int n,int val,List<Integer> res,int max)
{
if(cur>n)
return;
if(cur==n&&val<max)
res.add(val);
for(int i =index;i<arr.length;i++) {
helper(arr, i+1,cur+1, n, val + arr[i],res,max);
}
}

Java题解

class Solution {
public List<String> readBinaryWatch(int num) {
int[] hour = {1,2,4,8};
int[] minute ={1,2,4,8,16,32};
List<Integer> hourList = new ArrayList<>();
List<Integer> minuteList = new ArrayList<>();
List<String> ans = new ArrayList<>();
for(int i=0;i<=num;i++)
{
helper(hour,0,0,i,0,hourList,12);
helper(minute,0,0,num-i,0,minuteList,60);
for(int hi = 0;hi<hourList.size();hi++)
for(int mi =0;mi<minuteList.size();mi++)
{
String minVal = String.valueOf(minuteList.get(mi));
if(minVal.length()<2)
minVal = "0"+minVal;
ans.add(hourList.get(hi)+":"+minVal);
}
hourList = new ArrayList<>();
minuteList = new ArrayList<>();
}
Collections.sort(ans);
return ans;
} private void helper(int[] arr,int index,int cur,int n,int val,List<Integer> res,int max)
{
if(cur>n)
return;
if(cur==n&&val<max)
res.add(val);
for(int i =index;i<arr.length;i++) {
helper(arr, i+1,cur+1, n, val + arr[i],res,max);
}
} }

  

LeetCode:二进制手表【401】的更多相关文章

  1. Java实现 LeetCode 401 二进制手表

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

  2. 【leetcode 简单】 第九十三题 二进制手表

    二进制手表顶部有 4 个 LED 代表小时(0-11),底部的 6 个 LED 代表分钟(0-59). 每个 LED 代表一个 0 或 1,最低位在右侧. 例如,上面的二进制手表读取 “3:25”. ...

  3. [Swift]LeetCode401. 二进制手表 | Binary Watch

    A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom ...

  4. Leetcode401Binary Watch二进制手表

    二进制手表顶部有 4 个 LED 代表小时(0-11),底部的 6 个 LED 代表分钟(0-59). 每个 LED 代表一个 0 或 1,最低位在右侧. 给定一个非负整数 n 代表当前 LED 亮着 ...

  5. leetcode -- 二进制

    leetcode -- 二进制 在学习编程语言的运算符时,大部分语言都会有与,或等二进制运算符,我在初期学习这些运算符的时候,并没有重点留意这些运算符,并且在后续的业务代码中也没有频繁的使用过,直到后 ...

  6. 401 Binary Watch 二进制手表

    详见:https://leetcode.com/problems/binary-watch/description/ C++: class Solution { public: vector<s ...

  7. LeetCode 二进制问题

    338. Counting Bits(计算小于n的各个数值对应的二进制1的个数) 思路:通过奇偶判断,if i是偶数,a[i]=a[i/2],if i是奇数,a[i]=a[i-1]+1. class ...

  8. leetcode 二进制求和 python

    class Solution: def addBinary(self, a, b): """ :type a: str :type b: str :rtype: str ...

  9. [LeetCode&Python] Problem 401. Binary Watch

    A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom ...

随机推荐

  1. Mtx——Mobile Tutorial Series (LibGDX & MTX)

    http://moribitotechx.blogspot.co.uk/p/tutorial-series-libgdx-mtx.html —————————————————————————————— ...

  2. c++封装的发邮件类CSendMail

    项目需要做发邮件的功能,在网上找了一下代码,比较出名的SMailer编译不过(把那个Base64的encode拉到MailSender中实现就能过,但我搞不懂原来出错的原因,就不想用),另外找到了一个 ...

  3. 解决在SharePoint 2010/2013部署自己的Event Handler后,抛出”不能载入被引用的第三方的程序集&quot;的问题

    今天在处理客户的一个问题的时候.我们已经把我们SharePoint EventHandler依赖的第三方的TIBCO.EMS.dll注冊到GAC里面了,可是日志里面还是抛出了不能载入被引用的第三方的程 ...

  4. js禁止别人查看源码

    1.直接按F12 2.Ctrl+Shift+I查看 3.鼠标点击右键查看 4.Ctrl+u=view-source:+url 把以上三种状态都屏蔽掉就可以了,document有onkeydown(键盘 ...

  5. Java泛型解析(04):约束和局限性

    Java泛型解析(04):约束和局限性           前两节.认识和学习了泛型的限定以及通配符.刚開始学习的人可能须要一些时间去体会到泛型程序设计的优点和力量,特别是想成为库程序猿的同学就须要下 ...

  6. CentOS安装Oracle官方JRE

    CentOS自带的JRE是OpenJDK,因为一些原因,需要换用Oracle官方出品的JRE. Oracle JRE下载地址http://java.com/zh_CN/(下载时注意选择相应版本) 可以 ...

  7. hdu 4284(状压dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4284 思路:类似于poj3311:http://poj.org/problem?id=3311,首先f ...

  8. JAVA-各种类型之间转换 parse() 与valueOf()

    类型互转 1.各种类型转String 2.String转Bytes 3.数组转List 4.进制转换 5. parse 在 SimpleDateFormat 中是转换为Date类,其它的一些包装类都是 ...

  9. 《Sqlserver》通过端口 8080 连接到主机 localhost 的 TCP/IP 连接失败。错误:“驱动程序收到意外的登录前响应。请验证连接属性,并检查 SQL Server 的实例正在主机上运行,且在此端口接受

    1. 点击 开始 --> 所有程序 --> Microsoft SQL Server2005 --> 配置工具-->SQL Server configuration Manag ...

  10. c++ 指针(不断更新)

    c++指针只能说博大精深,在用的时候感觉好晕 1.指针类型转换 /* 在指针的强制类型转换:ptr1=(TYPE*)ptr2中,如果sizeof(ptr2的类型)大于sizeof(ptr1的类型), ...