1. 程式人生 > 其它 >leetcode-401. 二進位制手錶

leetcode-401. 二進位制手錶

話不多說,上程式碼,差點栽在一個簡單題手裡,也是我沒有想到的

其實呢,我有兩種思路

  • 一種就是把小時和分鐘的所有位表示的數字都枚舉出來,然後最後處理一下最後的輸出格式就行了,這個可行,但是廢手,而且容易出錯
  • 另外一種就是利用遞迴的方式,計算出每一步的所有可能值,不過這裡需要注意的是,會有不符合條件的組合,就需要剪枝,所以這也是回溯法

第二種方式:

class Solution {
    
    /**
     * @param Integer $turnedOn
     * @return String[]
     */
    public function readBinaryWatch($turnedOn) {
        // 時針最多有 4 個
        // 分針最多亮 6 個
        
        $hour    = [1, 2, 4, 8];
        $minutes = [1, 2, 4, 8, 16, 32];
        
        $ret = [];
        for ($i = 0; $i <= $turnedOn && $i < 4; $i++) {
            $hourPossible   = $this->getSetPossible($hour, $i, 11);
            $minutePossible = $this->getSetPossible($minutes, $turnedOn - $i, 59);
            
            foreach ($hourPossible as $hItem) {
                foreach ($minutePossible as $mItem) {
                    if ($mItem < 10) {
                        $mItem = '0' . $mItem;
                    }
                    $ret[] = $hItem . ':' . $mItem;
                }
            }
        }
        

        
        return $ret;
    }
    
    /**
     * @param $set
     * @param $count
     * @param $maxValue
     * @return array
     */
    public function getSetPossible($set, $count, $maxValue) {
        if ($count == 0) {
            return [0];
        }
        if ($count == 1) {
            return $set;
        }
        
        $setLen = count($set);
        
        $ret = [];
        
        // 第一個值的取值範圍
        $maxIndex = $setLen - $count;
        
        // 第一個值的取值範圍如果超過,那麼退出
        for ($i = 0; $i <= $maxIndex; $i++) {
            $possibleSet = $this->getSetPossible(array_slice($set, $i + 1), $count - 1, $maxValue);
            foreach ($possibleSet as $setItem) {
                if ($setItem + $set[$i] <= $maxValue) {
                    $ret[] = $set[$i] + $setItem;
                }
            }
        }
        
        return $ret;
    }
}