401. 二进制手表

401. 二进制手表

1.想法

如果这个手表只有一个刻度,例如只有小时,那么直接做回溯,可以得到所有的结果
但是现在是两个刻度,那么我们需要先确定其中的一个刻度的可选n值为多少然后再做回溯

回溯的过程是怎么样的?
第一种回溯方式: 全排列
例:[1,2,4],需要选择2个数字,那么我们可以选择多少个呢?
1.[1,2],[1,4],[2,1],[2,4],[4,1][4,2]



第二种:单排列


image.png

2.具体代码

 public List readBinaryWatch(int num) {

        List result = new ArrayList<>();
        int[] hours = new int[]{1,2,4,8};
        int[] minutes = new int[]{1,2,4,8,16,32};
        String hour = null;
        String minute = null;

       //如果num>4,即hour可以选完,
        int hourMaxValue = num >= 4 ? 4 : num;
        for(int i=0;i<=hourMaxValue;i++){
            List hourSet = new ArrayList<>();
            List minuteSet = new ArrayList<>();
            getMyTime(hours,i,0,0,12,0,hourSet);
            getMyTime(minutes,num-i,0,0,60,0,minuteSet);
            //如果给hour分配的方式导致没有可分配的方案直接跳过
            if(i!=0&&hourSet.size()==0)continue;
            //同理给minute的也一样
            if((num-i)!=0&&minuteSet.size()==0)continue;

            if(i==0){
                hour = "0";
                for(Integer item:minuteSet){
                    if(item<10){
                        minute = "0"+item;
                    }else{
                        minute = ""+item;
                    }
                    result.add(hour+":"+minute);
                }
            }
            else if(num - i ==0){
                minute = "00";
                for(Integer hourItem:hourSet){
                    hour = ""+hourItem;
                    result.add(hour+":"+minute);
                }
            }else{
                for(Integer hourItem:hourSet){
                    for(Integer minuteItem:minuteSet){
                        hour = ""+hourItem;
                        if(minuteItem<10){
                            minute = "0"+minuteItem;
                        }else{
                            minute = ""+minuteItem;
                        }
                        result.add(hour+":"+minute);
                    }
                }
            }



        }

        return result;
    }
    /*
    ** values 代表了所有分钟和小时可能的取值
    * maxCount代表了最大能选几个
    * choiceCount代表了现在选了几个了
    * index代表了选取的指针
    * maxValue代表了最大的小时或者分钟取值
    * tempValue代表了现在已经取了多大的值
    * resultSet代表了现在可能取值的集合
     */
    private void getMyTime(int[] values, int maxCount, int choiceCount,int index, int maxValue, int tempValue, List resultSet) {
        //如果现取值大于 =最大取值  return
        if(tempValue >= maxValue || maxCount==0)return;
        //已经选取够了
        if(choiceCount == maxCount){
            resultSet.add(tempValue);
        }
        //现在没有可选的了
        else if(index == values.length)return;
        else{
            //第一种情况,选择index的值
            getMyTime(values,maxCount,choiceCount+1,index+1,maxValue,tempValue+values[index],resultSet);
            //第二种情况,不选择index的值
            getMyTime(values,maxCount,choiceCount,index+1,maxValue,tempValue,resultSet);
        }
    }


}

你可能感兴趣的:(401. 二进制手表)