题目:
给定一个字符串str,只由‘X’和‘.’两种字符构成。
‘X’表示墙,不能放灯,也不需要点亮
‘.’表示居民点,可以放灯,需要点亮
如果灯放在i位置,可以让i-1,i和i+1三个位置被点亮
返回如果点亮str中所有需要点亮的位置,至少需要几盏
图示:
1、暴力解决方案
1.1、思路:
观察题目要求,我的思路是,每个点都可以选择放灯或不放灯(X一定不能放灯)。
那么我们可以从开头位置开始遍历
index位置选择放灯,然后去index+1位置找可能性。
idnex位置选择不放灯,然后去index+1位置找可能性。
直至遍历完毕,然后判断该可能性是否可以照亮所有。
最后从所有可能性中选择最优的方案。
1.2、代码:
//方案1:暴力方案
public static int minLight1(String road) {
if (road == null || road.length() == 0) {
return 0;
}
return process(road.toCharArray(), 0, new HashSet<>());
}
//str[index......] 位置,自由选择放灯还是不放等
//str[0,index-1]位置呢?已经做完决定了,那么放了灯的位置存放在lights集合中
//求出所有都能照亮的方案,并且在这些有效的方案中,返回最少需要多少盏灯
public static int process(char[] str, int index, HashSet<Integer> lights) {
if (index == str.length) {//说明已经遍历结束了
for (int i = 0; i < str.length; i++) {
//当前位置是点的时候,如果此位置的前后都没有灯,那么代表此时的方案为无效
if (str[i] != 'X') {
if (!lights.contains(i - 1) &&
!lights.contains(i) &&
!lights.contains(i + 1)) {
return Integer.MAX_VALUE;
}
}
}
return lights.size();
} else {
//当前不管是X还是点,都可以选择不放灯(X一定不能放)。
//也就是当前index位置不放灯,你去index+1位置给我返回最好的放灯数目
int no = process(str, index + 1, lights);
int yes = Integer.MAX_VALUE;
//如果index位置是点,那么我可以做出一个放灯的决定
if (str[index] == '.') {
//把需要放灯的位置加入到lights集合中,用完之后记得要移除掉
lights.add(index);
yes = process(str, index + 1, lights);
lights.remove(index);
}
//从当前位置不放灯和放灯得到的值之中取最小值
return Math.min(no, yes);
}
}
2、贪心解决方案
1.1、思路:
观察题目要求,我们可以考虑,如何不用关心前面的结果,只与后面的有关呢?如果当前是一个X,那么继续看下一个。如果当前是点,则我们看下一个位置是什么?如果也是点,则灯的位置应该就是在第二个位置,这就是我们的贪心策略,选择靠后的位置放灯,此时,当我们把第二个位置放灯后,我们根本就不用考虑第三个位置了,因为第三个位置无论是什么,都已经涵盖在灯的范围内了,此时直接跳到第四个位置重新判断。 同时,当第二个位置不是点时,说明只能在第一个位置放灯,此时,直接跳到第三个位置判断。
1.2、代码:
//方案2:贪心算法(我总是在当前步做出最右的决定)
public static int minLight2(String road) {
char[] str = road.toCharArray();
int index = 0;
int light = 0;
while (index < str.length) {
if (str[index] == 'X') {//如果当前位置是X,直接跳转到下一个位置去
index++;
} else {
//如果位置是点,那么一定需要添加一盏灯了
light++;
if (index + 1 == str.length) {//如果当前位置的下一个正好到末尾了,那么直接退出
break;
} else {
if (str[index + 1] == 'X') {
//如果当前位置是X,比如(.X),那么你就去index+2位置去做决定
index = index + 2;
} else {
//如果当前位置是点,比如(..),那么你就去index+3位置去决定
index = index + 3;
}
}
}
}
return light;
}