LeetCode:二进制手表【401】
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”。
題目分析
這道題目標注為簡單題,但感覺做起來比較費勁,雖然最后寫出來了,但感覺代碼很冗余。討論有很多非常巧妙的辦法,需要運用數學方法,我是絕對想不出來的。
我的思路是這樣的,題目意思是在小時數組{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, skiptempList.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);}}}
?
轉載于:https://www.cnblogs.com/MrSaver/p/9962717.html
總結
以上是生活随笔為你收集整理的LeetCode:二进制手表【401】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不可能不爱的 XCODE 9:最新功能详
- 下一篇: 记一次微信APP支付开发返回-1的坑