leetcode-401. 二进制手表

话不多说,上代码,差点栽在一个简单题手里,也是我没有想到的

其实呢,我有两种思路

  • 一种就是把小时和分钟的所有位表示的数字都枚举出来,然后最后处理一下最后的输出格式就行了,这个可行,但是废手,而且容易出错
  • 另外一种就是利用递归的方式,计算出每一步的所有可能值

第一种方式:暴力破解,是真的暴力

class Solution {
    
   /**
     * @param Integer $turnedOn
     * @return String[]
     */
    public function readBinaryWatch($turnedOn) {
        if ($turnedOn > 8) {
            return [];
        }
        
        $hourSet   = [
            0 => [0],
            1 => [1, 2, 4, 8],
            2 => [3, 5, 9, 6, 10],
            3 => [7, 11],
        ];
        $minuteSet = [
            0 => [0],
            1 => [1, 2, 4, 8, 16, 32],
            2 => [3,5,9,17,33,6,10,18,34,12,20,36,24,40,48],
            3 => [7,11,19,35,13,21,37,25,41,49,14,22,38,26,42,50,28,44,52,56],
            4 => [15,23,39,27,43,51,29,45,53,57,30,46,54,58],
            5 => [31,47,55,59],
        ];
        
        $hourPos = [];
        for ($i = 0; $i < $turnedOn+1 && $i < 4; $i++) {
            // 时针有几个亮起
            $hRet = $hourSet[$i];
            $mRet = $minuteSet[$turnedOn - $i];
            foreach ($hRet as $hItem) {
                foreach ($mRet as $mItem) {
                    if ($mItem < 10) {
                        $mItem = '0'.$mItem;
                    }
                    $ret[] = $hItem.':'.$mItem;
                }
            }
        }
    

        
        return $ret;
    }
}

第二种方式:回溯法

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;
    }
}

最终,这一题也没有阻挡住我继续做 lc easy 题的步伐

原文地址:https://www.cnblogs.com/wudanyang/p/14881538.html