LeetCode:二進位制手錶【401】
阿新 • • 發佈:2018-11-15
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, 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); } } }