我正在尝试使用Backtracking来解决LeetCode中的Binary Watch问题。
我的代码在下面(不工作)
public static void binaryWatchHelper(List<Integer>hours, List<Integer> mins,
int num , List<String> possibleTimes,int hoursSum,int minsSum) {
//System.out.println( num + " - " + hours + " - " + mins );
if(num==0) {
String m = minsSum <10?("0"+minsSum):""+minsSum;
possibleTimes.add(hoursSum +":"+m);
}
else {
for(int i=0;i<(hours.size()+mins.size());i++) {
if(i<hours.size()) {
int hr =hours.remove(i);
hoursSum+=hr;
if(hoursSum<=11)
binaryWatchHelper(hours, mins, num-1, possibleTimes, hoursSum, minsSum);
hours.add(i,hr);
hoursSum-=hr;
} else {
int mi =mins.remove(i-hours.size());
minsSum+=mi;
if(minsSum<=59)
binaryWatchHelper(hours, mins, num-1, possibleTimes, hoursSum, minsSum);
mins.add(i-hours.size(),mi);
minsSum-=mi;
}
}
}
}
我在leetcode讨论页面找到了以下代码(C ++),它运行正常。
void helper(vector<string>& res, pair<int, int> time, int num, int start_point) {
if (num == 0) {
res.push_back(to_string(time.first) + (time.second < 10 ? ":0" : ":") + to_string(time.second));
return;
}
for (int i = start_point; i < hour.size() + minute.size(); i ++)
if (i < hour.size()) {
time.first += hour[i];
if (time.first < 12) helper(res, time, num - 1, i + 1); // "hour" should be less than 12.
time.first -= hour[i];
} else {
time.second += minute[i - hour.size()];
if (time.second < 60) helper(res, time, num - 1, i + 1); // "minute" should be less than 60.
time.second -= minute[i - hour.size()];
}
}
上面的c ++算法非常类似于我所写的。但我的代码不起作用。谁能解释我,我错过了什么?
我没有传递startIndex,而是删除元素。但为什么我的代码不起作用?
我尝试打印堆栈跟踪调用,当然两者都非常不同。谁能指出我错过了什么?
我的输出结果不正确。
我的代码输出n = 2
[3:00, 5:00, 9:00, 1:01, 1:02, 1:04, 1:08, 1:16, 1:32, 3:00, 6:00, 10:00, 2:01, 2:02, 2:04, 2:08, 2:16, 2:32, 5:00, 6:00, 4:01, 4:02, 4:04, 4:08, 4:16, 4:32, 9:00, 10:00, 8:01, 8:02, 8:04, 8:08, 8:16, 8:32, 1:01, 2:01, 4:01, 8:01, 0:03, 0:05, 0:09, 0:17, 0:33, 1:02, 2:02, 4:02, 8:02, 0:03, 0:06, 0:10, 0:18, 0:34, 1:04, 2:04, 4:04, 8:04, 0:05, 0:06, 0:12, 0:20, 0:36, 1:08, 2:08, 4:08, 8:08, 0:09, 0:10, 0:12, 0:24, 0:40, 1:16, 2:16, 4:16, 8:16, 0:17, 0:18, 0:20, 0:24, 0:48, 1:32, 2:32, 4:32, 8:32, 0:33, 0:34, 0:36, 0:40, 0:48]
C ++代码输出:
[3:00, 5:00, 9:00, 1:01, 1:02, 1:04, 1:08, 1:16, 1:32, 6:00, 10:00, 2:01, 2:02, 2:04, 2:08, 2:16, 2:32, 4:01, 4:02, 4:04, 4:08, 4:16, 4:32, 8:01, 8:02, 8:04, 8:08, 8:16, 8:32, 0:03, 0:05, 0:09, 0:17, 0:33, 0:06, 0:10, 0:18, 0:34, 0:12, 0:20, 0:36, 0:24, 0:40, 0:48]
我的电话追踪为num = 2
2 - [1, 2, 4, 8] - [1, 2, 4, 8, 16, 32]
1 - [2, 4, 8] - [1, 2, 4, 8, 16, 32]
0 - [4, 8] - [1, 2, 4, 8, 16, 32]
0 - [2, 8] - [1, 2, 4, 8, 16, 32]
0 - [2, 4] - [1, 2, 4, 8, 16, 32]
0 - [2, 4, 8] - [2, 4, 8, 16, 32]
0 - [2, 4, 8] - [1, 4, 8, 16, 32]
0 - [2, 4, 8] - [1, 2, 8, 16, 32]
0 - [2, 4, 8] - [1, 2, 4, 16, 32]
0 - [2, 4, 8] - [1, 2, 4, 8, 32]
0 - [2, 4, 8] - [1, 2, 4, 8, 16]
1 - [1, 4, 8] - [1, 2, 4, 8, 16, 32]
0 - [4, 8] - [1, 2, 4, 8, 16, 32]
0 - [1, 8] - [1, 2, 4, 8, 16, 32]
0 - [1, 4] - [1, 2, 4, 8, 16, 32]
0 - [1, 4, 8] - [2, 4, 8, 16, 32]
0 - [1, 4, 8] - [1, 4, 8, 16, 32]
0 - [1, 4, 8] - [1, 2, 8, 16, 32]
0 - [1, 4, 8] - [1, 2, 4, 16, 32]
0 - [1, 4, 8] - [1, 2, 4, 8, 32]
0 - [1, 4, 8] - [1, 2, 4, 8, 16]
1 - [1, 2, 8] - [1, 2, 4, 8, 16, 32]
0 - [2, 8] - [1, 2, 4, 8, 16, 32]
0 - [1, 8] - [1, 2, 4, 8, 16, 32]
0 - [1, 2, 8] - [2, 4, 8, 16, 32]
0 - [1, 2, 8] - [1, 4, 8, 16, 32]
0 - [1, 2, 8] - [1, 2, 8, 16, 32]
0 - [1, 2, 8] - [1, 2, 4, 16, 32]
0 - [1, 2, 8] - [1, 2, 4, 8, 32]
0 - [1, 2, 8] - [1, 2, 4, 8, 16]
1 - [1, 2, 4] - [1, 2, 4, 8, 16, 32]
0 - [2, 4] - [1, 2, 4, 8, 16, 32]
0 - [1, 4] - [1, 2, 4, 8, 16, 32]
0 - [1, 2, 4] - [2, 4, 8, 16, 32]
0 - [1, 2, 4] - [1, 4, 8, 16, 32]
0 - [1, 2, 4] - [1, 2, 8, 16, 32]
0 - [1, 2, 4] - [1, 2, 4, 16, 32]
0 - [1, 2, 4] - [1, 2, 4, 8, 32]
0 - [1, 2, 4] - [1, 2, 4, 8, 16]
1 - [1, 2, 4, 8] - [2, 4, 8, 16, 32]
0 - [2, 4, 8] - [2, 4, 8, 16, 32]
0 - [1, 4, 8] - [2, 4, 8, 16, 32]
0 - [1, 2, 8] - [2, 4, 8, 16, 32]
0 - [1, 2, 4] - [2, 4, 8, 16, 32]
0 - [1, 2, 4, 8] - [4, 8, 16, 32]
0 - [1, 2, 4, 8] - [2, 8, 16, 32]
0 - [1, 2, 4, 8] - [2, 4, 16, 32]
0 - [1, 2, 4, 8] - [2, 4, 8, 32]
0 - [1, 2, 4, 8] - [2, 4, 8, 16]
1 - [1, 2, 4, 8] - [1, 4, 8, 16, 32]
0 - [2, 4, 8] - [1, 4, 8, 16, 32]
0 - [1, 4, 8] - [1, 4, 8, 16, 32]
0 - [1, 2, 8] - [1, 4, 8, 16, 32]
0 - [1, 2, 4] - [1, 4, 8, 16, 32]
0 - [1, 2, 4, 8] - [4, 8, 16, 32]
0 - [1, 2, 4, 8] - [1, 8, 16, 32]
0 - [1, 2, 4, 8] - [1, 4, 16, 32]
0 - [1, 2, 4, 8] - [1, 4, 8, 32]
0 - [1, 2, 4, 8] - [1, 4, 8, 16]
1 - [1, 2, 4, 8] - [1, 2, 8, 16, 32]
0 - [2, 4, 8] - [1, 2, 8, 16, 32]
0 - [1, 4, 8] - [1, 2, 8, 16, 32]
0 - [1, 2, 8] - [1, 2, 8, 16, 32]
0 - [1, 2, 4] - [1, 2, 8, 16, 32]
0 - [1, 2, 4, 8] - [2, 8, 16, 32]
0 - [1, 2, 4, 8] - [1, 8, 16, 32]
0 - [1, 2, 4, 8] - [1, 2, 16, 32]
0 - [1, 2, 4, 8] - [1, 2, 8, 32]
0 - [1, 2, 4, 8] - [1, 2, 8, 16]
1 - [1, 2, 4, 8] - [1, 2, 4, 16, 32]
0 - [2, 4, 8] - [1, 2, 4, 16, 32]
0 - [1, 4, 8] - [1, 2, 4, 16, 32]
0 - [1, 2, 8] - [1, 2, 4, 16, 32]
0 - [1, 2, 4] - [1, 2, 4, 16, 32]
0 - [1, 2, 4, 8] - [2, 4, 16, 32]
0 - [1, 2, 4, 8] - [1, 4, 16, 32]
0 - [1, 2, 4, 8] - [1, 2, 16, 32]
0 - [1, 2, 4, 8] - [1, 2, 4, 32]
0 - [1, 2, 4, 8] - [1, 2, 4, 16]
1 - [1, 2, 4, 8] - [1, 2, 4, 8, 32]
0 - [2, 4, 8] - [1, 2, 4, 8, 32]
0 - [1, 4, 8] - [1, 2, 4, 8, 32]
0 - [1, 2, 8] - [1, 2, 4, 8, 32]
0 - [1, 2, 4] - [1, 2, 4, 8, 32]
0 - [1, 2, 4, 8] - [2, 4, 8, 32]
0 - [1, 2, 4, 8] - [1, 4, 8, 32]
0 - [1, 2, 4, 8] - [1, 2, 8, 32]
0 - [1, 2, 4, 8] - [1, 2, 4, 32]
0 - [1, 2, 4, 8] - [1, 2, 4, 8]
1 - [1, 2, 4, 8] - [1, 2, 4, 8, 16]
0 - [2, 4, 8] - [1, 2, 4, 8, 16]
0 - [1, 4, 8] - [1, 2, 4, 8, 16]
0 - [1, 2, 8] - [1, 2, 4, 8, 16]
0 - [1, 2, 4] - [1, 2, 4, 8, 16]
0 - [1, 2, 4, 8] - [2, 4, 8, 16]
0 - [1, 2, 4, 8] - [1, 4, 8, 16]
0 - [1, 2, 4, 8] - [1, 2, 8, 16]
0 - [1, 2, 4, 8] - [1, 2, 4, 16]
0 - [1, 2, 4, 8] - [1, 2, 4, 8]
C ++代码调用跟踪:
2 - [1, 2, 4, 8] - [1, 2, 4, 8, 16, 32]
1 - [2, 4, 8] - [1, 2, 4, 8, 16, 32]
0 - [4, 8] - [1, 2, 4, 8, 16, 32]
0 - [8] - [1, 2, 4, 8, 16, 32]
0 - [] - [1, 2, 4, 8, 16, 32]
0 - [] - [2, 4, 8, 16, 32]
0 - [] - [4, 8, 16, 32]
0 - [] - [8, 16, 32]
0 - [] - [16, 32]
0 - [] - [32]
0 - [] - []
1 - [4, 8] - [1, 2, 4, 8, 16, 32]
0 - [8] - [1, 2, 4, 8, 16, 32]
0 - [] - [1, 2, 4, 8, 16, 32]
0 - [] - [2, 4, 8, 16, 32]
0 - [] - [4, 8, 16, 32]
0 - [] - [8, 16, 32]
0 - [] - [16, 32]
0 - [] - [32]
0 - [] - []
1 - [8] - [1, 2, 4, 8, 16, 32]
0 - [] - [2, 4, 8, 16, 32]
0 - [] - [4, 8, 16, 32]
0 - [] - [8, 16, 32]
0 - [] - [16, 32]
0 - [] - [32]
0 - [] - []
1 - [] - [1, 2, 4, 8, 16, 32]
0 - [] - [2, 4, 8, 16, 32]
0 - [] - [4, 8, 16, 32]
0 - [] - [8, 16, 32]
0 - [] - [16, 32]
0 - [] - [32]
0 - [] - []
1 - [] - [2, 4, 8, 16, 32]
0 - [] - [4, 8, 16, 32]
0 - [] - [8, 16, 32]
0 - [] - [16, 32]
0 - [] - [32]
0 - [] - []
1 - [] - [4, 8, 16, 32]
0 - [] - [8, 16, 32]
0 - [] - [16, 32]
0 - [] - [32]
0 - [] - []
1 - [] - [8, 16, 32]
0 - [] - [16, 32]
0 - [] - [32]
0 - [] - []
1 - [] - [16, 32]
0 - [] - [32]
0 - [] - []
1 - [] - [32]
0 - [] - []
1 - [] - []
感谢。
答案 0 :(得分:0)
解决这个问题的回溯方法是多余的。您可以使用一些位操作技术来解决此问题。
指向观察
用于表示小时和表示分钟的设置位总数应等于传递的参数n
。
您有0 - 11
小时和0 - 59
分钟。使用两个for循环并且仅选择小时h
和分钟m
,其中设置位的总和等于n
,您可以使您的解决方案更加优雅和快速。问题的目标还在于测试你的位操作技能。
public List<String> readBinaryWatch(int n) {
List<String> ret = new ArrayList<>();
for(int h = 0; h < 12; h++) {
for(int m = 0; m < 60; m++) {
if(Integer.bitCount(h) + Integer.bitCount(m) == n) { // Checking whether the current h and m combination is a valid result.
//If the sum of their set bits is equal to nthen the combination is a valid result and add that combination to result
ret.add(String.format("%d:%02d",h,m));
}
}
}
return ret;
}
答案 1 :(得分:0)
我同意上面的答案,我也通过这种方式解决了这个问题。
我也有一些不同的解决方案。你可以在这里找到它 https://github.com/yan-khonski-it/leetcode/tree/master/src/main/java/com/yk/leetcode/binary_watch
这个想法是,您可以为每个小时LED计算小时组合。例如,0个led表示0小时,1个led表示1、2、4、8中的任何选项。 更多细节 https://leetcode.com/problems/binary-watch/discuss/601642/C%2B%2B-straight-solution-with-tables-of-hours-and-minutes
同样适用于分钟。领先一分钟意味着在1,2,4,8,16,32分钟内可以选择。
现在,您的手表上有nLeds
个LED数量。 nLeds = hoursLeds + minutesLeds
。在这种情况下,您将拥有所有可能的小时组合和分钟组合,只需加入它们即可。
现在,您可以从the link above中找到带有已定义值的表。您可以对这些表进行硬编码,也可以自己构建它们。
// Hours combinations depending on leds number
private static final int[] hours0 = calculateLedsNumbers(0, 12);
private static final int[] hours1 = calculateLedsNumbers(1, 12);
private static final int[] hours2 = calculateLedsNumbers(2, 12);
private static final int[] hours3 = calculateLedsNumbers(3, 12);
private static final int[] hours4 = calculateLedsNumbers(4, 12);
// Minutes combinations depending on leds number
private static final int[] minutes0 = calculateLedsNumbers(0, 60);
private static final int[] minutes1 = calculateLedsNumbers(1, 60);
private static final int[] minutes2 = calculateLedsNumbers(2, 60);
private static final int[] minutes3 = calculateLedsNumbers(3, 60);
private static final int[] minutes4 = calculateLedsNumbers(4, 60);
private static final int[] minutes5 = calculateLedsNumbers(5, 60);
private static final int[] minutes6 = calculateLedsNumbers(6, 60);
然后循环浏览小时和分钟的所有可能组合,并将它们组合起来。
final List<String> result = new ArrayList<>(191);
for (int hoursLeds = 0; hoursLeds < 4; hoursLeds++) {
int[] possibleHours = getHoursFromLed(hoursLeds);
for (int minutesLeds = 0; minutesLeds < 6; minutesLeds++) {
if (hoursLeds + minutesLeds > nLeds) {
break;
}
if (hoursLeds + minutesLeds == nLeds) {
int [] possibleMinutes = getMinutesFromLed(minutesLeds);
combineHoursAndMinutes(possibleHours, possibleMinutes, result);
}
}
}
并结合
private static void combineHoursAndMinutes(int[] possibleHours, int[] possibleMinutes, List<String> result) {
for (int possibleHour : possibleHours) {
for (int possibleMinute : possibleMinutes) {
// Same as String.format("%d:%02d", possibleHour, possibleMinute), but faster.
result.add(hoursFormatted[possibleHour] + minutesFormatted[possibleMinute]);
}
}
}